创建相似对象,就交给『工厂模式』吧

源码:

源代码C#

系列导航:

目录

定义(Factory Pattern):

用来创建目标对象的类,将相似对象的创建工作统一到一个类来完成。

一、简单工厂模式:

代码:

    /// <summary>/// 产品枚举/// </summary>public enum ProductEnum{ConcreateProductA,ConcreateProductB}/// <summary>/// 简单工厂模式:/// 简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。/// 不修改代码的话,是无法扩展的。(如果增加新的产品,需要增加工厂的Swith分支)/// 不符合【开放封闭原则】/// </summary>public static class SimpleFactory{public static AbstractCar Create(ProductEnum productType){switch (productType){case ProductEnum.ConcreateProductA:return new ConcreateCarA();case ProductEnum.ConcreateProductB:return new ConcreateCarB();default:return null;}}}
        /// <summary>/// 测试简单工厂模式/// </summary>private static void TestSimpleFactory(){Console.WriteLine("简单工厂模式:");var productA = SimpleFactory.Create(ProductEnum.ConcreateProductA);productA.GetInfo();Console.ReadLine();}

简单工厂模式运行结果

优缺点:

工厂类包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。对于客户端来说,去除了对具体产品的依赖。
不符合【OCP】。

应用场景:

当工厂类负责创建的对象比较少时可以考虑使用简单工厂模式。


二、反射工厂模式(基于简单工厂模式的拓展)

通过反射,以完成工厂对对象的创建。可以最大限度的解耦。

代码:

    /// <summary>/// 反射工厂模式/// 是针对简单工厂模式的一种改进/// </summary>public static class ReflectFactory{public static AbstractCar Create(string typeName){Type type = Type.GetType(typeName, true, true);var instance = type?.Assembly.CreateInstance(typeName) as AbstractCar;return instance;}}
        /// <summary>/// 测试反射工厂模式/// </summary>private static void TestReflectFactory(){Console.WriteLine("反射工厂模式:");var productB = ReflectFactory.Create("FactoryPattern.ConcreateCarB");productB.GetInfo();Console.ReadLine();}

反射工厂模式运行结果

PS:反射工厂模式可以和配置文件配合使用,效果更佳


三、工厂方法模式

定义:

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法将类的实例化延长到子类。

类图:

工厂方法模式类图

启示:

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

代码:

    /// <summary>/// 工厂方法模式:/// 工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。/// 在同一等级结构中,支持增加任意产品。/// 符合【开放封闭原则】,但随着产品类的增加,对应的工厂也会随之增多/// </summary>public interface IFactoryMethod{AbstractCar Create();}public class ConcreateFactoryA:IFactoryMethod{public AbstractCar Create(){return new ConcreateCarA();}}public class ConcreateFactoryB : IFactoryMethod{public AbstractCar Create(){return new ConcreateCarB();}}
        /// <summary>/// 测试工厂方法模式/// </summary>private static void TestFactoryMethod(){Console.WriteLine("工厂方法模式:");IFactoryMethod factoryB =new ConcreateFactoryB();var productB = factoryB.Create();productB.GetInfo();Console.ReadLine();}

工厂方法模式运行结果

优缺点:

符合【OCP】,但随着产品类的增加,对应的工厂类也会随之增多。
工厂方法模式实现时,客户端需要决定实例化哪个工厂来创建对象。工厂方法把简单工厂的内部创建对象的逻辑判断移到了客户端。如果需要修改,只需要修改客户端即可!

应用场景:

单一产品的创建。


三、抽象工厂模式

定义:

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。

类图:

抽象工厂模式类图

启示:

抽象工厂是应对产品族概念的,比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。

代码:

    /// <summary>/// 抽象工厂模式:/// 抽象工厂是应对产品族概念的,比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。/// 应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。/// </summary>public interface IAbstractFactory{AbstractCar CreateCar();AbstractBus CreateBus();}/// <summary>/// 宝马工厂/// </summary>public class BMWFactory:IAbstractFactory{public AbstractCar CreateCar(){return new ConcreateCarA();}public AbstractBus CreateBus(){return new ConcreateBusA();}}/// <summary>/// 比亚迪工厂/// </summary>public class BYDFactory : IAbstractFactory{public AbstractCar CreateCar(){return new ConcreateCarB();}public AbstractBus CreateBus(){return new ConcreateBusB();}}
/// <summary>/// 测试抽象工厂模式/// </summary>private static void TestAbstractFactory(){Console.WriteLine("抽象工厂模式:");var bmwFactory = new BMWFactory();bmwFactory.CreateCar().GetInfo();bmwFactory.CreateBus().GetInfo();var bydFactory = new BYDFactory();bydFactory.CreateCar().GetInfo();bydFactory.CreateBus().GetInfo();Console.ReadLine();}

抽象工厂模式运行结果

优缺点:

应对产品族概念而生,增加新的产品线很容易,但是无法增加新的产品。

应用场景:

一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
这个系统有多个系列产品,而系统中只消费其中某一系列产品
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。


总结:

简单工厂:简单实用,但违反开放封闭;
工厂方法:开放封闭,单一产品;
抽象工厂:开放封闭,多个产品;
反射工厂:可以最大限度的解耦。

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

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

相关文章

《ASP.NET Core 6框架揭秘》实例演示[26]:跟踪应用接收的每一次请求

很多人可能对ASP.NET Core框架自身记录的诊断日志并不关心&#xff0c;其实这些日志对纠错排错和性能监控提供了很有用的信息。如果需要创建一个APM&#xff08;Application Performance Management&#xff09;系统来监控ASP.NET Core应用处理请求的性能及出现的异常&#xff…

C语言循环为1404的循环,考试,求大神帮忙,C语言,小弟感激不尽

若有定义语句&#xff1a;int a10; double b3.14;&#xff0c;则表达式Aab值的类型是___________。  (1)A).char B)int C) double D)float(2)若有定义语句&#xff1a;int x12,y8,z;&#xff0c;在其后执行语句z0.9x/y;&#xff0c;则z的值为___________。A)1.9 B)1 C)2 D)2.…

js题集19

1.实现斐波那契数列。达到题目中的效果。不知道斐波那契数列是啥的请自行百度。 function fibonacci(){ } var ffibonacci(); for(var i0;i<10;i){ console.log(f()); } //output:按顺序输出斐波那契数列的数字。 eg&#xff1a; 1 2 3 5 8 13 21 34 55 89转载于:https://ww…

阿里云Maven镜像配置

2019独角兽企业重金招聘Python工程师标准>>> <mirror><id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> …

c语言中有12个球,数学老师做不出来的一道逻辑推理题

同志们 那个球不一定轻啊正确的是平分三份 取两分称if(平)。。。。。。在未称过的4球中取两个放左边 和标准的球称(称过的球一定标准)。。。。。。if(平)。。。。。。。。。。。。在两次都未称过的球中取一个 和标准的称。。。。。。。。。。。。if(平)。。。。。。。。。。。。…

WPF 实现弹幕效果

WPF 实现弹幕效果控件名&#xff1a;BarrageExample作者&#xff1a;WPFDevelopersOrg原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40&#xff1b;Visual Studio 2022;项目使用 MIT 开源许可协议&#xff1b;此篇代码目的只…

js题集23

1.实现函数--defaultArguments 功能如下&#xff1a; function add(a,b) { return ab;}; var add_ defaultArguments(add,{b:9}); add_(10); // returns 19 add_(10,7); // returns 17 add_(); // returns NaN add_ defaultArguments(add_,{b:3, a:2}); add_(10); // returns…

iteritems()与items()

iteritems&#xff1a;以迭代器对象返回字典键值对 item:以列表形式返回字典键值对 >>> dic {a:3,c:1,b:2} >>> print dic.iteritems() <dictionary-itemiterator object at 0x7fa381599628> >>> print dic.items() [(a, 3), (c, 1), (b, 2)…

WPF效果第一百九十八篇之模块对比

前面效果中分享了彩色马蹄图的效果和范围内拖拽;这不大假期的时间反正没啥事就在家撸代码;今天又是LisBox实现的效果,看最终效果:1、刚开始一朋友说用DataGrid来实现.首先把行对象转换成列对象,至于控制列的话,就后台重新赋值对象来控制前台.我是觉得太费劲直接放弃了;还是首选…

android 与后台通信,Android后台线程和UI线程通讯实例

本节向你展示如何在任务中发送数据给UI线程里的对象&#xff0c;这个特性允许你在后台线程工作&#xff0c;完了在UI线程展示结果。在UI线程定义一个HandlerHandler是Android系统线程管理框架里的一部分。一个Handler对象接收消息&#xff0c;并且运行代码来处理消息。正常情况…

saltstack的状态文件

saltstack状态文件设定&#xff1a;编辑/etc/salt/master&#xff0c;修改其中关于“设置文件的目录”的设置&#xff1a;说明&#xff1a;注意语法格式&#xff0c;顶格/冒号/两个空格state_top: top.sls # The state system uses a "top" file to tell the minions…

POJ 2798:二进制转换十六进制

很郁闷&#xff0c;这道题一直WA&#xff0c;然而本地我测了好几组数据都是通过的&#xff0c;上网找了网友陈宇龙加油加油加油的AC的代码&#xff0c;http://blog.csdn.net/Since_natural_ran/article/details/51742149&#xff0c;发现没有什么不同。。。很无语。。 #include…

【Shashlik.EventBus】.NET 事件总线,分布式事务最终一致性简介

分布式事务、CAP定理、事件总线&#xff0c;在当前微服务、分布式、集群大行其道的架构前提下&#xff0c;是不可逃避的几个关键字&#xff0c;在此不会过多阐述相关的理论知识。Shashlik.EventBus就是一个基于.NET6的开源事件总线解决方案&#xff0c;同时也是分布式事务最终一…

5个超实用的Visual Studio插件

工欲善其事&#xff0c;必先利其器,整理的一些我必装的5款Visual Studio插件&#xff0c;希望你们能get到。01 CodeMaidCodeMaid快速整理代码文件&#xff0c;规范你的代码&#xff0c;提高代码阅读体验。代码自动对齐&#xff0c;格式化代码&#xff08;ps&#xff1a;不用再按…

BZOJ1509: [NOI2003]逃学的小孩(树的直径)

Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1126 Solved: 567[Submit][Status][Discuss]Description Input 第一行是两个整数N&#xff08;3  N  200000&#xff09;和M&#xff0c;分别表示居住点总数和街道总数。以下M行&#xff0c;每行给出一条街道的信息。第i1行…

Blazor University (52)依赖注入 —— 拥有多个依赖项:正确的方式

原文链接&#xff1a;https://blazor-university.com/dependency-injection/component-scoped-dependencies/owning-multiple-dependencies-the-right-way/拥有多个依赖项&#xff1a;正确的方式在上一节[1]中&#xff0c;我们看到了将多个拥有的依赖项注入组件的错误方法。本节…

Gradle 1.12用户指南翻译——第五十四章. 构建原生二进制文件

其他章节的翻译请参见&#xff1a;http://blog.csdn.net/column/details/gradle-translation.html翻译项目请关注Github上的地址&#xff1a;https://github.com/msdx/gradledoc本文翻译所在分支&#xff1a;https://github.com/msdx/gradledoc/tree/1.12。直接浏览双语版的文档…

android 调用c wcf服务,如何使用命名管道从c调用WCF方法?

更新&#xff1a;通过协议here,我无法弄清楚未知的信封记录.我在网上找不到任何例子.原版的&#xff1a;我有以下WCF服务static void Main(string[] args){var inst new PlusFiver();using (ServiceHost host new ServiceHost(inst,new Uri[] { new Uri("net.pipe://loc…

VK Cup 2015 - Qualification Round 1 A. Reposts(树)

传送门 Description One day Polycarp published a funny picture in a social network making a poll about the color of his handle. Many of his friends started reposting Polycarps joke to their news feed. Some of them reposted the reposts and so on. These event…

Lombok@Builder和@NoArgsConstructor冲突

问题 今天在使用lombok简化model类时。使用Builder建造者模式。报以下异常 解决办法。 去掉NoArgsConstructor添加AllArgsConstructor源码分析 下图是编译后的源码 只使用Builder会自动创建全参构造器。而添加上NoArgsConstructor后就不会自动产生全参构造器