设计模式之工厂方法模式
一、引言
在简单工厂模式中讲到简单工厂模式的缺点,有一点是——简单工厂模式系统难以扩展,一旦添加新产品就不得不修改简单工厂方法,这样就会造成简单工厂的实现逻辑过于复杂,工厂方法模式可以解决简单工厂模式中存在的这个问题,下面就具体看看工厂模式是如何解决该问题的。
二、工厂方法模式的实现
工厂方法模式之所以可以解决简单工厂的模式,是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口,这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点。下面看下工厂模式的具体实现代码(这里还是以简单工厂模式中计算器的例子来实现):
(一)具体类运算操作的接口
namespace 抽象工厂方法 { /// <summary> /// 定义一个运算操作的接口,运算类继承此接口 /// </summary> interface Ioperation { /// <summary> /// 获取运算结果的接口 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> double GetReult(double a, double b); } }
(二)运算大工厂接口
声明一个运算工厂的接口,类型为具体运算类的接口,所有具体的运算接口都继承与此,方法为创造运算的具体实例
namespace 抽象工厂方法 { /// <summary> /// 运算接口(超级大工厂) /// </summary> interface IFactory { Ioperation CreateOperation(); } }
(三)建立加法运算工厂
建立加法运算工厂,创建具体的加法运算实例
namespace 抽象工厂方法 { /// <summary> /// 加法运算工厂 /// </summary> class AddFactory : IFactory { /// <summary> /// 获得加法运算的具体实例 /// </summary> /// <returns></returns> public Ioperation CreateOperation() { return new AddOperation(); } } }
(四)开始我们的加法运算类
我们建一个类,为加法操作的类,继承与具体类运算的接口,返回一个具体的值
namespace 抽象工厂方法 { /// <summary> /// 加法运算类 /// </summary> class AddOperation: Ioperation { public double GetReult(double a, double b) { return a + b; } } }
(五)开始享用我们的工厂的产品
在客户端实例化一个加法工厂,我们在加法工厂中创建加法对象,调用我们应有的加法方法,进行计算
namespace 抽象工厂方法 { class Program { static void Main(string[] args) { //先获得加法运算的工厂实例(先来个加法运算的厂家) IFactory factory = new AddFactory(); //加法运算的厂家开始为我们制造一个运算加法的实例 Ioperation oper = factory.CreateOperation(); //加法实例开始具体的运算 double result= oper.GetReult(13,15); Console.WriteLine(result); Console.ReadLine(); } } }
使用工厂方法实现的系统,如果系统需要添加新产品时,我们可以利用多态性来完成系统的扩展,对于抽象工厂类(创建具体实例的工厂)和具体工厂(具体的运算工厂)中的代码都不需要做任何改动。例如,我们加一个减法的运算,此时我们只需要定义一个减法具体工厂类和减法类就可以。而不用像简单工厂模式中那样去修改工厂类中的实现(具体指添加case语句)。
三、工厂方法模式的UML图
讲解完工厂模式的具体实现之后,让我们看下工厂模式中各类之间的UML图:
从UML图可以看出,在工厂方法模式中,工厂类与具体产品类具有平行的等级结构,它们之间是一一对应的。针对UML图的解释如下:
IFactory接口:充当接口工厂角色,任何具体工厂都必须继承该接口
AddFactory:充当具体工厂角色,用来创建具体产品
Ioperation:充当抽象产品角色,具体产品的接口。任何具体产品都应该继承该类
AddOperation类:充当具体产品角色,实现抽象产品接口中获取结果值的方法,由具体工厂类创建,它们之间有一一对应的关系。
四、 工厂方法模式与简单工厂模式
工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象(接口也可以)工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类(多态性)。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了"开放-封闭"原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
参考资料:程杰《大话设计模式》