工厂方法(FactoryMethod)模式是类的创建模式,其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。工厂方法模式又称为多态工厂模式.
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。
意图:
定义一个用于创建对象的接口,让子类决定实例化哪一个类 。
Factory Method 使一个类的实例化延迟到其子类.
适用性:
1) 当一个类不知道它所必须创建对象的类的时候
2) 当一个类希望由它的子类来制定它所创建对象的时候
3) 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望
将哪一个帮助子类是代理者这一信息局部化的时候
比如:一个类可以创建一个对象,但是具体创建这个类的职责是由这个类的
子类来完成的,但是一个类的子类可能有多个,你希望是哪个子类去创建这个
对象呢?,也就是信息局部化,所谓局部化就是由特定的子类来创建想要创建的那个
对象,假设A这个子类创建B这个对象,B这个子类来创建C这个对象,说的就是局
部化的意思.
工厂方法模式的构成
产品角色(Prodict):定义产品的接口,工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
具体产品角色(ConcreteProduct):实现接口Product的接口,这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
工厂角色(Creator):声明工厂方法(FactoryMethod),返回一个产品,是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
具体工厂角色(ConcreteCreator):实现FactoryMethod方法,由客户调用,返回一个产品的实例,这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
举例:
比如有一个兵工厂,兵工厂有各种武器,可以创建坦克,可以创建大炮,冲锋枪等等.但是不可能一个工厂它可以创建所有的武器(这就是简单工厂的缺陷),那么由创建坦克的工厂去完成坦克的创建,由冲锋抢的工厂完成冲锋枪的创建,创建冲锋枪和创建坦克的工厂都是具体工厂的角色,它们都是兵工厂(工厂角色),创建出来的冲锋枪和坦克是具体产品角色,它们都是兵器(产品角色).
同理现在有两个手机工厂分别是诺基亚和三星,诺基亚工厂创建诺基亚手机,三星工厂创建三星手机,相反就不行.这样就总结出两个工厂和两个具体产品,而不同的产品是由不同的工厂制造出来的. 就像前面说的坦克这个产品是由制造坦克的工厂制造出来的,飞机这个产品是由制造飞机的这个工厂制造出来的,它们之间不会乱,每个具体工厂它都会创建它所应该创建的那个具体产品对象,一个具体的工厂对应一个具体产品对象
工厂方法模式与简单工厂模式:
工厂方法模式与简单工厂模式再结构上的不同不是很明显。工厂方法类的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口,或者有共同的抽象父类。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好的符合了"开放-封闭"原则。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
Class Diagram:
SequenceDiagram:
class Clinet { static void Main(string[] args) { MobileFactory factory; Mobile mobile; factory = new NoKiaFactory(); mobile = factory.ProduceMobile(); mobile.Call(); factory = new MotorolaFactory(); mobile = factory.ProduceMobile(); mobile.Call(); Console.ReadKey(); } } /// <summary> /// 产品角色(手机) /// </summary> public interface Mobile { void Call(); } /// <summary> /// 工厂角色(创建手机) /// </summary> interface MobileFactory { Mobile ProduceMobile(); } /// <summary> /// 具体的产品(Motorola) /// </summary> public class Motorola : Mobile { public void Call() { Console.WriteLine("摩托罗拉手机!"); } } /// <summary> /// 具体的产品(Nokia) /// </summary> public class Nokia : Mobile { public void Call() { Console.WriteLine("诺基亚手机!"); } } /// <summary> /// 具体的工厂角色,创建诺基亚手机 /// </summary> public class NoKiaFactory : MobileFactory { #region MobileFactory 成员 public Mobile ProduceMobile() { Console.Write("诺基亚工厂制造了:"); return new Nokia(); } #endregion } /// <summary> /// 具体的工厂角色,创建摩托罗拉手机 /// </summary> public class MotorolaFactory : MobileFactory { #region MobileFactory 成员 public Mobile ProduceMobile() { Console.Write("摩托罗拉工厂制造了:"); return new Motorola(); } #endregion }