工厂方法模式是一种创建型设计模式,它的模式动机是:定义一个用户创建对象的接口,让子类决定实例哪一个类。Factory Method使一个类的实例化延迟到子类。
当一个类不知道它所要创建的对象或希望由它的子类来指定它所创建的对象时,可使用该模式。该模式隔离了产品的具体实现,调用者只关心产品的接口,降低了类的对象的使用者和具体类型之间的耦合性。使系统具有高扩展性,符合了开闭原则。
工厂方法模式组成:(1)抽象产品类(2)抽象工厂类(3)具体产品类(4)具体工厂类
以下是一个实例,例如现在要在游戏中创建各种士兵:刀兵,枪兵,弓箭兵。工厂方法模式是用来提供创建对象的最佳方式的模式,所以在该模式中无论创建什么对象,都有两个变化点,第一是每个对象的定义不同:刀兵用刀,弓箭兵用弓箭;刀兵攻击低防御高,弓箭兵攻击高防御低。这些属性会根据创建的是不同种类的士兵对象而变化,所以要抽象这些属性和定义的变化,就要抽象出士兵类(抽象产品类)。如下图1:
该抽象产品类中的抽象方法在子类(具体产品类)中实现,会实现不同的产品属性,正是变化点。图2图3正是两个具体产品类,定义了两个具体的士兵兵种:
另外,每次创建士兵对象都要new A(),new B(),要new出不同的对象这也是变化点,所以要抽象出生产士兵的工厂类(抽象工厂类),如下图3:
该抽象工厂类中的抽象方法在子类(具体工厂类)中实现,会new出不同的对象,这是第二个变化点。图5图6是两个具体工厂类,实现了创建两种不同的士兵对象:
以上的两个抽象类中各自包含了抽象方法,这些抽象方法的目的就是要延迟到子类中去实现,而之所以要延迟到子类中实现,是因为现在不知道以后还会出现哪些变化。我们不知道以后会new 出什么士兵,不知道该士兵有什么武器。正是因为我们不知道,所以要抽象,要延迟实现,保证以后扩展的时候方便。综上,什么东西在变化,就抽象什么。
该模式的缺点是:类的个数太多,增加了系统的复杂度和抽象性,而且该模式下的抽象产品类只抽象了一类产品,以上便是只抽象了士兵,但是诸如农民,矿工之类,不具有武器这类抽象属性,便不能创建。这个问题可用抽象工厂模式解决。