简单工厂增加一个新的具体产品类之外,还需要修改工厂类的代码,这就使得整个设计在一定程度上违反了“开闭原则”。
先定义一个抽象工厂,然后定义具体工厂,在具体工厂中增加新的具体产品。
问题:一个类需要实例化另一个类的派生类,但不知道是那一个。Factory Method允许派生类进行决策。
也就是说,我原来的工厂想实例化一个具体产品类,但是这个产品不一定是谁,如果有一个新的产品过来了,我还得修改工厂类,那我现在该怎么办呢?
解决方案:派生类对实例化哪个类和如何实例化做出决策
也就是说,如果新增加了一个产品,我就自己去派生出一个具体工厂类(我就是抽象工厂),然后让具体工厂类去实例化新增加的具体产品类。这样抽象工厂就满足了开闭原则。
在抽象类(Creator)中使用一个抽象方法(Create),需要实例化一个被包含对象的时候(ConcreteProduct1),抽象类的代码将引用此方法,但是不知道需要的对象是哪一个
顾名思义:工厂方法,也就是在抽象工厂中定义一个能够产生具体产品类的抽象方法,然后让具体工厂去实现这个方法,然后返回一个具体的产品类。
如果只有一个具体工厂类,可以改造为Simple factory 。
问题来了:现在每个具体工厂只能生产一个产品,随着产品的增加,会导致产生大量的工厂类,系统开销也会变大。
如果一些产品是不同属性的,也就是通过不同的接口实现的。这样就会形成一个产品族,我想建立一个产品族的具体产品时,我该怎么办呢?难道我要创建N个抽象工厂吗?通过上述的方法,写出N遍才能得到?这样显然不满足代码复用原则。
所以我们得想办法解决它。具体见下文。
应用实例:
在射击游戏中,冲锋枪、狙击枪、手枪等不同武器(Weapon)的外观、使用方法和杀伤力都不相同,玩家可以使用不同的武器,而且游戏升级时还可以增加新的武器,无需对现有系统做太多修改,如何设计武器系统?
由于是设计的是武器系统,武器又有多种实现,但是武器的种类又不固定,由于产品等级结构单一,所以采用了工厂方法。具体实现参考图示。