工厂方法模式
定义:定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
举例:(我们依然举pizza工厂的例子,不过这个例子中,pizza产地有两个:伦敦和纽约)。添加了一个新的产地,如果用简单工厂模式的的话,我们要去修改工厂代码,并且会增加一堆的if else语句。而工厂方法模式克服了简单工厂要修改代码的缺点,它会直接创建两个工厂,纽约工厂和伦敦工厂。类图如下:
OrderPizza中有个抽象的方法:
abstract Pizza createPizza();
两个工厂类继承OrderPizza并实现抽象方法:
public class LDOrderPizza extends OrderPizza { Pizza createPizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new LDCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } } public class NYOrderPizza extends OrderPizza { Pizza createPizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new NYCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new NYPepperPizza(); } return pizza; } }
通过不同的工厂会得到不同的实例化的对象,PizzaStroe的代码如下:
public class PizzaStroe { public static void main(String[] args) { OrderPizza mOrderPizza; mOrderPizza = new NYOrderPizza(); } }
解决了简单工厂模式的问题:增加一个新的pizza产地(北京),只要增加一个BJOrderPizza类:
public class BJOrderPizza extends OrderPizza { Pizza createPizza(String ordertype) { Pizza pizza = null; if (ordertype.equals("cheese")) { pizza = new LDCheesePizza(); } else if (ordertype.equals("pepper")) { pizza = new LDPepperPizza(); } return pizza; } }
其实这个模式的好处就是,如果你现在想增加一个功能,只需做一个实现类就OK了,无需去改动现成的代码。这样做,拓展性较好!
工厂方法存在的问题与解决方法:客户端需要创建类的具体的实例。简单来说就是用户要订纽约工厂的披萨,他必须去纽约工厂,想订伦敦工厂的披萨,必须去伦敦工厂。 当伦敦工厂和纽约工厂发生变化了,用户也要跟着变化,这无疑就增加了用户的操作复杂性。为了解决这一问题,我们可以把工厂类抽象为接口,用户只需要去找默认的工厂提出自己的需求(传入参数),便能得到自己想要产品,而不用根据产品去寻找不同的工厂,方便用户操作。