C#设计模式——抽象工厂模式(重点)


文章目录

  • 项目地址
  • 一、抽象工厂模式
    • 1.1 特性
    • 1.2 使用反射获取特性标记的类
    • 1.3 完整代码


项目地址

  • 教程作者:
  • 教程地址:
  • 代码仓库地址:
  • 所用到的框架和插件:
dbt 
airflow

一、抽象工厂模式

  1. 工厂方法模式依然存在一个问题就是,一堆的 switch用来根据符号判断;if或者switch都是描述了一段关系,运算符和具体工厂对象的对应关系,如何直接根据符号就可以自动获取对应的类,并且自动创建实例呢?

1.1 特性

  • 什么是特性?
    通过Attribute特性,根据输入的符号,直接将符号+和cal = new Add();对应起来,特性类似于一个装饰器,装饰器装饰的类,就拥有了这个对应关系;
    往往和反射一起结合使用
  1. 创建一个特性,用来描述运算符和具体类的关系
//①使用特性Attribute来标记类的作用
public class OperToFactoryAttribute : Attribute
{public string Oper { get; } public OperToFactoryAttribute(string oper){this.Oper = oper;}
}
  1. 使用创建好的特性去标记运算类
//②使用特性Attribute来标记类的作用
//2.通过子类实现加法的创建
[OperToFactoryAttribute("+")]
public class AddFactory : ICalFactory
{public ICal GetCalculator(){return new Add();}
}

至此,运算符和对应需要的类已经创建完成,程序运行后,当用户输入了符号,我们应该通过这个对应关系,就可以找到这个类,然后进行实例化,计算

1.2 使用反射获取特性标记的类

  1. 根据用户的操作符,返回一个对象,
  2. 通过字典来存储对应关系
  3. 通过反射获取所有的程序集
  4. 获取所有的类型
  5. 通过判断获取AddFactory,SubFactory,MulFactory,DivFactory,找到他们的共性,都是继承了ICalFactory接口,并且排除ICalFactory自己

1.3 完整代码


using System.ComponentModel;
using System.Reflection;public class program
{static void Main(){Console.WriteLine("输入number1:");double d1 = Convert.ToDouble(Console.ReadLine());Console.WriteLine("输入number2:");double d2 = Convert.ToDouble(Console.ReadLine());Console.WriteLine("输入运算符:");string op = Console.ReadLine();//13.执行反射里的构造函数,创建符号和类的对应关系的字典ReflectionFactory rf = new ReflectionFactory();//15.通过运算符来创建工厂ICalFactory calFactory = rf.CreateFactory(op);//16.通过具体的运算类来计算结果ICal calculator = calFactory.GetCalculator();double res = calculator.getResult(d1, d2);Console.WriteLine(res);}
}//1.创建特性Attribute来标记类的作用
public class OperToFactoryAttribute : Attribute
{public string Oper { get; } public OperToFactoryAttribute(string oper){this.Oper = oper;}
}//声明一个接口,先将创建对象的这个过程封装成抽象
public interface ICalFactory
{ICal GetCalculator();
}//3.通过反射,程序运行后,获取特性标记的类,然后通过反射创建对象
public class ReflectionFactory
{//4.创建字典,存储符号和类的对应关系Dictionary<string, ICalFactory> dic = new Dictionary<string, ICalFactory>();//5.构造函数public ReflectionFactory(){//6.通过反射获取所有的程序集Assembly asm = Assembly.GetExecutingAssembly();//7.获取所有的类型Type[] types = asm.GetTypes();foreach (var type in types){//8.通过判断获取AddFactory,SubFactory,MulFactory,DivFactoryif (typeof(ICalFactory).IsAssignableFrom(type) && !type.IsInterface){//9.获取特性OperToFactoryAttribute otfa = type.GetCustomAttribute<OperToFactoryAttribute>();//10.判断是否为空if (otfa != null){//11.将特性和类的对应关系存储到字典中,根据type创建对象dic.Add(otfa.Oper, Activator.CreateInstance(type) as ICalFactory);}}}}//12.通过运算符来创建工厂public ICalFactory CreateFactory(string oper){//13. 从字典里查找对应关系if (dic.ContainsKey(oper)){return dic[oper];}return null;}
}//2.使用特性Attribute来标记类的作用
[OperToFactoryAttribute("+")]
public class AddFactory : ICalFactory
{public ICal GetCalculator(){return new Add();}
}[OperToFactoryAttribute("-")]
public class SubFactory : ICalFactory
{public ICal GetCalculator(){return new Sub();}
}[OperToFactoryAttribute("*")]
public class MulFactory : ICalFactory
{public ICal GetCalculator(){return new Mul();}
}[OperToFactoryAttribute("/")]
public class DivFactory : ICalFactory
{public ICal GetCalculator(){return new Div();}
}//计算类的接口
public interface ICal
{double getResult(double num1, double num2);
}public class Add : ICal
{public double getResult(double num1, double num2){return num1 + num2;}
}
public class Sub : ICal
{public double getResult(double num1, double num2){return num1 - num2;}
}public class Mul : ICal
{public double getResult(double num1, double num2){return num1 * num2;}
}public class Div : ICal
{public double getResult(double num1, double num2){return num1 / num2;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/62227.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LAMP环境的部署

一、软件安装介绍 在Linux系统中安装软件有rpm安装、yum安装、源码安装等方法&#xff0c;在这里主要给大家介绍 yum 安装&#xff0c;这是一种最简单方便的一种安装方法。 YUM&#xff08;Yellow dog Upadate Modifie&#xff09;是改进版的 RPM 管理器&#xff0c;很好地解…

『VUE』elementUI dialog的子组件created生命周期不刷新(详细图文注释)

目录 1. 测试代码分析令人迷惑的效果 分析原因解决方法 如何在dialog中反复触发created呢?总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 主要是在做表单的时候想要有一个编辑表单在dialog弹窗中出现,同时dialog调用的封装的…

项目实战:基于深度学习的人脸表情识别系统设计与实现

大家好&#xff0c;人脸表情识别是计算机视觉领域中的一个重要研究方向&#xff0c;它涉及到对人类情感状态的理解和分析。随着深度学习技术的发展&#xff0c;基于深度学习的人脸表情识别系统因其高精度和强大的特征学习能力而受到广泛关注。本文旨在探讨基于深度学习的人脸表…

QChart数据可视化

目录 一、QChart基本介绍 1.1 QChart基本概念与用途 1.2 主要类的介绍 1.2.1 QChartView类 1.2.2 QChart类 1.2.3QAbstractSeries类 1.2.4 QAbstractAxis类 1.2.5 QLegendMarker 二、与图表交互 1. 动态绘制数据 2. 深入数据 3. 缩放和滚动 4. 鼠标悬停 三、主题 …

Chrome和edge浏览器如何为任何网站强制暗模式

前言 因为我的编辑器是黑色&#xff0c;可能是看的时间长了比较喜欢这种颜色了&#xff0c;感觉白色有些刺眼。尤其是看文章时&#xff0c;两边的空白纯白色&#xff0c;所以强迫症搜素设置了谷歌浏览器和edge如何设置成黑色。 Chrome和edge浏览器如何为任何网站强制暗模式 前…

使用 Elastic 收集 Windows 遥测数据:ETW Filebeat 输入简介

作者&#xff1a;来自 Elastic Chema Martinez 在安全领域&#xff0c;能够使用 Windows 主机的系统遥测数据为监控、故障排除和保护 IT 环境开辟了新的可能性。意识到这一点&#xff0c;Elastic 推出了专注于 Windows 事件跟踪 (ETW) 的新功能 - 这是一种强大的 Windows 原生机…

k8s网络服务

k8s 中向外界提供服务的几种方法port-forward、NodePort&#xff0c;以及 更加常用的提供服务的资源ingress。 1 kubectl port-forward service/redis 6379:6379 现在k8s中有一个pod运行在6379&#xff0c;本机访问映射到6379上&#xff0c;它可以针对部署&#xff0c;服务&…

微信小程序按字母顺序渲染城市 功能实现详细讲解

在微信小程序功能搭建中&#xff0c;按字母渲染城市会用到多个ES6的方法&#xff0c;如reduce&#xff0c;map&#xff0c;Object.entries()&#xff0c;Object.keys() &#xff0c;需要组合熟练掌握&#xff0c;才能优雅的处理数据完成渲染。 目录 一、数据分析 二、数据处理 …

前端JavaScript(一)---基本介绍

Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言&#xff0c;主要目的是为了解决服务器端语言&#xff0c;比如Perl&#xff0c;遗留的速度问题&#xff0c;为客户提供更流畅的浏览效果。当时服务端需要对…

git的使用(简洁版)

什么是 Git&#xff1f; Git 是一个分布式版本控制系统 (DVCS)&#xff0c;用于跟踪文件的更改并协调多人之间的工作。它由 Linus Torvalds 在 2005 年创建&#xff0c;最初是为了管理 Linux 内核的开发。Git 的主要目标是提供高效、易用的版本控制工具&#xff0c;使得开发者…

vscode可以编译通过c++项目,但头文件有红色波浪线的问题

1、打开 VSCode 的设置&#xff0c;可以通过快捷键 Ctrl Shift P 打开命令面板&#xff0c;然后搜索并选择 “C/C: Edit Configurations (JSON)” 命令&#xff0c;这将在 .vscode 文件夹中创建或修改 c_cpp_properties.json 文件 {"configurations": [{"name…

VS Code前端常用插件

通用类 auto close tag auto rename tag beautify class autocomplete for html Code Runner css peek dash JavaScript Debugger document this eslint font-awesome codes for html filesize git history gitlens html css support HTMLHint htmltagwrap indenticator Intel…

Android 16 开发者预览版抢先使用

Android 16 开发者预览版 获取 Android 16在 Google Pixel 设备上获取 Android 16设置 Android 模拟器 设置 Android 16 SDK获取 Android Studio安装 SDK更新应用的 build 配置 获取 Android 16 你可以通过以下任一方式获取 Android 16 在 Google Pixel 设备上获取 Android 1…

解析生成对抗网络(GAN):原理与应用

目录 一、引言 二、生成对抗网络原理 &#xff08;一&#xff09;基本架构 &#xff08;二&#xff09;训练过程 三、生成对抗网络的应用 &#xff08;一&#xff09;图像生成 无条件图像生成&#xff1a; &#xff08;二&#xff09;数据增强 &#xff08;三&#xff…

docker 安装mysql8.4.0

1、拉取mysql8.4.0镜像 docker pullmysql:8.4.0-oraclelinux8查看镜像 docker images2、新建宿主机本地目录&#xff1a;用来挂载MySQL容器所产生的数据的目录 mkdir -p /home/admin/data/mysql /home/admin/logs/mysql /home/admin/conf/mysql3、在/home/admin/conf/mysql目…

ABAP OOALV模板

自用模板&#xff0c;可能存在问题 一、主程序 *&---------------------------------------------------------------------* *& Report ZVIA_OO_ALV *&---------------------------------------------------------------------* REPORT ZVIA_OO_ALV.INCLUDE ZVI…

DeepSpeed-chat RLHF实战

轩辕-6bRLHF落地实战 模型介绍&#xff1a;轩辕-6B 模型库 (modelscope.cn) 1.1偏好数据集构建 ​ 1.1.1Prompt构建 1.1.2 Response生成 保证RM训练数据和测试数据分布一致 使用模型来生成response&#xff0c;为了评价response的质量&#xff0c;可以提高采样参数中的…

通过抓包,使用frida定位加密位置

首先我们抓取一下我们要测试的app的某一个目标api&#xff0c;通过抓api的包&#xff0c;得到关键字。 例如&#xff1a;关键字&#xff1a;x-sap-ri 我们得到想要的关键字后&#xff0c;通过拦截 类&#xff0c;寻找我们的关键字&#xff0c;及找到发包收包的位置&#xff0c…

无线WiFi网络版毫米波雷达人体传感器,智能家居节能减排照明有人无人识别

在这个科技日新月异的时代&#xff0c;智能家居已经不再是遥不可及的未来概念&#xff0c;而是悄然融入了我们的日常生活&#xff0c;为我们的生活带来了未有的便捷与舒适。今天&#xff0c;让我们一起探索一项创新性的智能家居技术——飞睿智能无线WiFi网络版毫米波雷达人体传…

Linux介绍与安装指南:从入门到精通

1. Linux简介 1.1 什么是Linux&#xff1f; Linux是一种基于Unix的操作系统&#xff0c;由Linus Torvalds于1991年首次发布。Linux的核心&#xff08;Kernel&#xff09;是开源的&#xff0c;允许任何人自由使用、修改和分发。Linux操作系统通常包括Linux内核、GNU工具集、图…