设计模式-工厂方法(Factory Method)
简述
工厂方法和抽象工厂两个设计模式很相似,很多人不了解两者的区别(包括我)。等把这五个创建型模式都介绍完后,我们再做一个总结。
功能
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。这个定义是一本《设计模式手册》的书中提到的,看起来很官方。
何处使用
当我们并不知道当前创建的对象到底属于哪一个类,或者希望一个类由它的子类来指定它所创建的对象的时候,可以使用工厂方法。嗯,这样的描述其实由来于《Head First Design Pattern》这本书,这本书非常明确的描述了抽象工厂和工厂方法的区别,希望有兴趣的朋友可以去看看。
或许这样说还是很多人不太理解,可以这么说工厂方法权力比较大,它像发号命令的老板,经常会命令自己的子类做一些事情,他并不在乎他们如何去做这些事情,只要能够满足他当前的需求就可以。通常我们买手机时为了避免充电的麻烦,会购买一个或两个备用电池,很多人不会购买原厂出产的因为价格会比较高,当然符合同样机型的电池可以出自不同的厂家,他们会在电池的制作工艺或者使用材料上存在一些差异,但是不用担心它们同样符合这台手机的正常使用。也就是说工厂方法用来创建某一对象,但它不需要知道或者根本就不知道自己将要创建出什么样的对象,负责创建这一对象的是它的子类(看来它像老板一样指使员工去做事一样)。
设计
我们需要一个抽象的产品类,如此一来就可以由它衍生出不同的产品。还需要一个抽象的创建者类它可以通过工厂方法来创建产品,同样由它也要衍生出来不同的具体创建者,通过重写父类的工厂方法来创建各自的具体产品,从下面的 UML 图可以看出来,具体的创建者类依赖于各自的产品类。这样一来我们对各个类之间的关系有了一些了解,通过它们之间的关系就可以绘制出工厂方法的类图。
实现
当知道要做什么并且如何去做才能达成目标时,我认为实现起来就是时间的问题,下面是 Baidu 到的一段代码,稍作修改:
using System; public class Test { static void Main() { Console.WriteLine("Hello"); Creator[] creators = new Creator[2]; creators[0] = new ConcreteCreatorA(); creators[1] = new ConcreteCreatorB(); foreach(Creator creator in creators) { Product product = creator.FactoryMethod(); Console.WriteLine("Created {0}", product.GetType().Name); } } } public abstract class Product { } public class ConcreteProductA : Product { } public class ConcreteProductB : Product { } public abstract class Creator { public abstract Product FactoryMethod(); } public class ConcreteCreatorA : Creator { public override Product FactoryMethod() { return new ConcreteProductA(); } } public class ConcreteCreatorB : Creator { public override Product FactoryMethod() { return new ConcreteProductB(); } }
由此看来要想实现我们的工厂方法我们必须要做到:
- 可以衍生并创造各自产品的创建者类;
- 可以衍生不同产品的产品类
To be continued! @ Design Patterns