设计模式之工厂家族
2015-12-13 18:29
330 查看
工厂家族是指创建型模式中的三个名称很相像的模式,即简单工厂、工厂方法和抽象工厂模式,鼎鼎大名的工厂家族使我们编写代码更加简练,更加容易维护、扩展和复用,虽然工厂家族们有其各自的优点,但同时局限性也是不可避免的,下面对三工厂进行一个简单的总结。
一、简单工厂模式
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,其实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。主要是解决如何去实例化对象的问题,下面以实现计算器功能为例:
优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
缺点:简单工厂严格来说并不算一种设计模式,因为它违反了开放-封闭原则,简单工厂是通过分支来判断选择实例化哪一个类,如果需求更改,那么就要更改工厂类了,不仅对扩展开放了,对修改也开放了。
二、工厂方法模式
工厂方法模式主要针对的是开放-封闭原则,它定义一个用于创建对象的借口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。也就是说,在子类中去实例化对象,让子类做到需要什么就实例化什么。还以计算器为例:
关键代码:
工厂方法模式式简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
三、抽象工厂模式
抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。以数据访问程序为例,如果数据库中只有一个User表,那么使用简单工厂模式,定义一个IUser接口和访问IUser的工厂接口就可以实现了,但如果再增加一个Department表,那么就要用抽象工厂模式了,在工厂接口中增加接口方法,也要在工厂类中增加实例化方法。
关键代码:
1、易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2、让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
缺点:
产品扩展非常困难,由于抽象工厂模式解决的是涉及到多个产品系列的问题,那么再进行产品扩展需要进行大批量的改动,所以有时候也要工厂家族的其他族员和反射等方法来对其改进。
小结
工厂家族虽然给编程带来了很多好处,各有其优点,但他们也各有其局限性,都不够灵活,设计模式的使用不是一成不变必须按套路来的,需要我们在实际情况中配合使用,从而做到面向对象,编程是门艺术,随着学习的不断深入,相信我们一定会达到炉火纯青,随手写出优美代码的程度的,fighting!!
一、简单工厂模式
简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,其实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。主要是解决如何去实例化对象的问题,下面以实现计算器功能为例:
namespace 简单工厂模式 { class Program { static void Main(string[] args) { try { Console.Write("请输入数字A:"); int strNumberA = Convert.ToInt32(Console.ReadLine()); //隐式转换 Console.Write("请选择运算符号(+、-、*、/)"); string stroperate = Console.ReadLine(); Console.Write("请输入数字B"); int strNumberB = Convert.ToInt32(Console.ReadLine()); Operation oper; oper = OperationFactory.createOperate("strOperation"); //获取运算符 oper.NumberA = strNumberA; //NumberA赋值 oper.NumberB = strNumberB; //NumberB赋值 double result = oper.GetResult(); //数值计算,获得结果 Console.WriteLine(result); } catch (Exception ex) { Console.WriteLine("您的输入有错:" + ex.Message); } } } //简单运算工厂类 public class OperationFactory { public static Operation createOperate(string operate) { Operation oper = null; switch (operate) //选择实例化类 { case "+": //条件判断 oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; } } //Operation运算类 public class Operation { private double _numberA = 0; private double _numberB = 0; public double NumberA //对私有变量赋值 { get { return _numberA; } set { _numberA = value; } } public double NumberB { get { return _numberB; } set { _numberB = value; } } public virtual double GetResult() //定义方法 { double result = 0; return result; } } //加减乘除类 class OperationAdd : Operation //加法类,继承运算类 { public override double GetResult() //继承父类GetResult方法 { double result = 0; result = NumberA + NumberB; return result; } } class OperationSub : Operation //减法类同加法类 { public override double GetResult() { double result = 0; result = NumberA - NumberB; return result; } } class OperationMul : Operation //乘法类同加法类 { public override double GetResult() { double result = 0; result = NumberA * NumberB; return result; } } class OperationDiv : Operation //除法类同加法类 { public override double GetResult() { double result = 0; if (NumberB == 0) throw new Exception("除数不能为0"); result = NumberA / NumberB; return result; } }
优点:工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。
缺点:简单工厂严格来说并不算一种设计模式,因为它违反了开放-封闭原则,简单工厂是通过分支来判断选择实例化哪一个类,如果需求更改,那么就要更改工厂类了,不仅对扩展开放了,对修改也开放了。
二、工厂方法模式
工厂方法模式主要针对的是开放-封闭原则,它定义一个用于创建对象的借口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。也就是说,在子类中去实例化对象,让子类做到需要什么就实例化什么。还以计算器为例:
关键代码:
//工厂借口 interface IFactory { Operation CreateOperation(); }
//具体工厂类(减法、乘法、除法同加法类) class AddFactory : IFactory //加法类工厂 { public Operation CreateOperation() { return new OperationAdd(); } }
//客户端实现 IFactory operFactory = new AddFactory(); //实例化加法类工厂 Operation oper=operFactory.CreateOperation (); //实例化加法运算类 oper.NumberA = 1; oper.NumberB = 2; double result = oper.GetResult();工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,也就是说将简单工厂的内部逻辑判断移到了客户端代码来进行,那么如果增加算法的话,虽然不用去改工厂类的case分支,但是需要到客户端去修改了。
工厂方法模式式简单工厂模式的进一步抽象和推广,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。但缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
三、抽象工厂模式
抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。以数据访问程序为例,如果数据库中只有一个User表,那么使用简单工厂模式,定义一个IUser接口和访问IUser的工厂接口就可以实现了,但如果再增加一个Department表,那么就要用抽象工厂模式了,在工厂接口中增加接口方法,也要在工厂类中增加实例化方法。
关键代码:
//SqlserverDepartment类,用于访问SQL Server的Department class sqlserverDepartment : IDepartment { public void Insert(Department department) { Console.WriteLine ("在SQL Server中给Department表增加一条记录"); } public Department GetDepartment(int id) { Console.WriteLine("在SQL Server中根据ID得到Department表一条记录"); return null; } } //IFactory接口,定义一个创建访问Department表对象的抽象的工厂接口 interface IFactory { IUser CreateUser(); IDepartment CreateDepartment(); //增加的接口方法 } //SQLServerFactory类,实现IFactory接口,实例化SQLserverUser和SQLserverDepartment class SqlServerFactory : IFactory { public IUser CreateUser() { return new SqlserverUser(); } public IDepartment CreateDepartment() //增加了SQLserverDepartment工厂 { return new sqlserverDepartment(); } }优点:
1、易于交换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2、让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
缺点:
产品扩展非常困难,由于抽象工厂模式解决的是涉及到多个产品系列的问题,那么再进行产品扩展需要进行大批量的改动,所以有时候也要工厂家族的其他族员和反射等方法来对其改进。
小结
工厂家族虽然给编程带来了很多好处,各有其优点,但他们也各有其局限性,都不够灵活,设计模式的使用不是一成不变必须按套路来的,需要我们在实际情况中配合使用,从而做到面向对象,编程是门艺术,随着学习的不断深入,相信我们一定会达到炉火纯青,随手写出优美代码的程度的,fighting!!
相关文章推荐
- net.sf.json在处理json对象转换为普通java实体对象时的问题和解决方案
- 【LeetCode】278 First Bad Version
- JSP精简见解
- 使用jQuery播放/暂停 HTML5视频
- 大型web系统数据缓存设计
- 显示意图激活另外一个Activity
- onetoone
- Android在onInterceptTouchEvent与onTouchEvent
- jquery特效(7)—弹出遮罩层且内容居中
- BZOJ 3224 普通平衡树
- 【HBOI2013】Ede的新背包问题
- WinExec 使用手记
- Spring MVC Controller单例陷阱
- 【C#】——out和ref区别
- JAVA泛型学习笔记
- securecrt同时向多个tab窗口发送相同的命令
- 《spring in action》笔记(一)
- OpenGL多重采样的初始化问题
- 生命的意义-周国平音频
- Kth Smallest Element in a BST