C#——工厂模式
之前我们接介绍了简单工厂,这次我们介绍一种更为常用的模式——工厂模式。
工厂方法模式Factory Method,又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做。该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。
开闭原则(OCP):)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。对于扩展是开放的,对于修改是关闭的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。也就是说,我们可以改变模块的功能。对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。实现开闭原则的关键就在于“抽象”。把系统的所有可能的行为抽象成一个抽象底层,这个抽象底层规定出所有的具体实现必须提供的方法的特征。作为系统设计的抽象层,要预见所有可能的扩展,从而使得在任何扩展情况下,系统的抽象底层不需修改;同时,由于可以从抽象底层导出一个或多个新的具体实现,可以改变系统的行为,因此系统设计对扩展是开放的。
之前简单工厂的核心工厂就是根据需求不断制造类的实例,现在我们将这个行为抽象化,就会达到多种效果:单一化,模块化,拓展性强,便于修改。主程序的代码可以不用动,只需要增加类就行了(实现某种功能的类,往往继承于一个接口)。下面看代码:
public interface IFactory { IPerson GetSay(); }
public interface IPerson { void Say(); }
public class Student : IPerson
{
public void Say()
{
Console.WriteLine("我是学生....");
}
}
public class Teacher : IPerson
{
public void Say()
{
Console.WriteLine("我是老师....");
}
}
public class StudentFactory : IFactory
{
public IPerson GetSay()
{
return new Student();
}
}
public class TeacherFactory : IFactory
{
public IPerson GetSay()
{
return new Teacher();
}
}
上面我们把最重要的两个东西都抽象画了——工厂和产品。产品IPerson我们就不说了还是遵循简单工厂。最大变化是这里的工厂IFactory不再直接参与生产,而是把这项具体工作将给了子类StudentFactory、TeachFactory,让他们去生产类的实例。将这个生产动作抽象化,完美的实现了开闭原则。下面是主程序调用:
<appSettings>
<add key="AssemblyPath" value="ConsoleApp2"/>
<add key="NameSpace" value="ConsoleApp2"/>
<add key="StudentFactory" value="StudentFactory"/>
</appSettings>
private static readonly string assemblyName = ConfigurationManager.AppSettings["AssemblyPath"];//程序集
private static readonly string nameSpace = ConfigurationManager.AppSettings["NameSpace"];//命名空间
private static readonly string className = ConfigurationManager.AppSettings["StudentFactory"];//类名 public static object CreateInstance(string assemblyName, string nameSpace, string className)
{
try
{
string fullName = nameSpace + "." + className;//命名空间.类型名
object ect = Assembly.Load(assemblyName).CreateInstance(fullName);//加载程序集,创建程序集里面的 命名空间.类型名 实例
return ect;//类型转换并返回
}
catch (Exception ex) { Console.WriteLine(ex.Message + "===" + ex.StackTrace); return false; }
} static void Main(string[] args)
{
IFactory ifc = CreateInstance(assemblyName, nameSpace, className) as IFactory;
IPerson ip = ifc.GetSay();
ip.Say();
Console.ReadKey();
}
这里有个技巧就是利用之前介绍过的反射,修改配置文件就可以创建类的实例。这里我们通过反射创建了StudentFactory的实例,然后利用类的多态特性,调用GetSay方法。得到继承于接口IPerson的子类实例,然后又利用类的多态特性,调用Say方法,最终完成。主程序中两次抽象,两次创建了类的实例,最开始还用到了反射,从头至尾,目的就是为了解耦,达到开闭的原则,便于以后的功能拓展。
参考:开闭原则、详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)
C#——工厂模式的更多相关文章
- 23种设计模式--工厂模式-Factory Pattern
一.工厂模式的介绍 工厂模式让我们相到的就是工厂,那么生活中的工厂是生产产品的,在代码中的工厂是生产实例的,在直白一点就是生产实例的类,代码中我们常用new关键字,那么这个new出来的实例 ...
- javascript工厂模式和构造函数模式创建对象
一.工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程(本书后面还将讨论其他设计模式及其在JavaScript 中的实现).考虑到在ECMAScript 中无法创 ...
- PHP设计模式(三)抽象工厂模式(Abstract Factory For PHP)
一.什么是抽象工厂模式 抽象工厂模式的用意为:给客户端提供一个接口,可以创建多个产品族中的产品对象 ,而且使用抽象工厂模式还要满足以下条件: 系统中有多个产品族,而系统一次只可能消费其中一族产品. 同 ...
- PHP设计模式(一)简单工厂模式 (Simple Factory For PHP)
最近天气变化无常,身为程序猿的寡人!~终究难耐天气的挑战,病倒了,果然,程序猿还需多保养自己的身体,有句话这么说:一生只有两件事能报复你:不够努力的辜负和过度消耗身体的后患.话不多说,开始吧. 一.什 ...
- 设计模式之工厂模式VS抽象工厂
一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类:1)简单工厂模式(Simple Factor ...
- 菜鸟理解的工厂模式(Factory Pattern)是什么样子的?
直接开始说了,不浪费园友宝贵的时间! 什么是工厂模式? 在学习前,先问一下:"它是什么?". 工厂模式,它是项目里面常用的设计模式之一. 它是属于创建型模式,简单的理解创建型模式就 ...
- PHP 面向对象编程和设计模式 (3/5) - 单例模式和工厂模式
PHP高级程序设计 学习笔记 2014.06.11 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容 ...
- 《JS设计模式笔记》构造函数和工厂模式创建对象
工厂模式 function createPerson (name,age,job) { var o=new Object(); o.name=name; o.age=age; o.job=job; o ...
- 从接口、抽象类到工厂模式再到JVM来总结一些问题
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习! 涉及到的知识点总结如下: 为什么使用接口? 接口和抽象类的区别 简单工厂模式总结 Java中new和newInstance的区别 J ...
- C#设计模式之简单工厂模式(Simple Factory)
1. 概述 简单工厂模式就是将一个类的实例化交给一个静态工厂来执行. 2. 使用频率 中 3. 模式结构 3.1 机构图 3.2 模式中的角色 Product:抽象类,把具体产品类公共的代码进行抽象和 ...
随机推荐
- QT .pro文件的学习收获
1. 载pro文件预定义宏: CONFIG(debug,debug|release){ DEFINES+=__DEBUG__ }else{ DEFINES+=__RELEASE__ macx:DEST ...
- ArcGIS For Android 的标绘与可视化
参考 1. CSDN 相关博文 2. ArcGIS for Android 离线数据空间分析--叠加分析 3. ArcGIS for Android Runtime100 基本操作(五)——绘制图层和 ...
- 【CV论文阅读】 Fast RCNN + SGD笔记
Fast RCNN的结构: 先从这幅图解释FAST RCNN的结构.首先,FAST RCNN的输入是包含两部分,image以及region proposal(在论文中叫做region of inter ...
- LintCode-分糖果
有 N 个小孩站成一列.每一个小孩有一个评级. 依照下面要求.给小孩分糖果: 每一个小孩至少得到一颗糖果. 评级越高的小孩能够得到很多其它的糖果. 需最少准备多少糖果? 您在真实的面试中是否遇到过这个 ...
- [Vue @Component] Load Vue Async Components
Vue provides a straight-forward syntax for loading components at runtime to help shave off initial b ...
- hdu5305(2015多校2)--Friends(状压,深搜)
Friends Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Su ...
- Centos 7 nginx-1.12.0编译安装
参考:http://www.nginx.cn/install 也不知道我的系统是否有这些依赖包,试试吧?缺少哪些我就装哪些吧,多踏点坑总是能学到点东西的. 获取nginx包 http://ngin ...
- Linux下一款可以使用命令行的pdf阅读器
Zathura是linux下一款用命令行控制打pdf阅读器,并且基本打使用方法和vim很相似.对于喜欢键盘操作的用户来说的确是一个不错的选择. ubuntu下的安装命令: sudo apt-get i ...
- 2015南阳CCPC G - Ancient Go dfs
G - Ancient Go Description Yu Zhou likes to play Go with Su Lu. From the historical research, we fou ...
- Web Tab, Project Properties
https://msdn.microsoft.com/en-us/library/aa983445(v=vs.100).aspx The Web tab of the project Properti ...