工厂模式是用来对创建对象的细节进行封装的一种模式。
工厂模式分为三种:(1)简单工厂(静态工厂);(2)工厂方法;(3)抽象工厂。
public class PizzaStore { SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) { this.factory = factory; } public Pizza orderPizza(String type){ Pizza pizza = null; pizza = factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
public class SimplePizzaFactory { public Pizza createPizza(String type) { Pizza pizza = null; if(type.equals("cheese")) { pizza = new CheesePizza(); } else if(type.equals("clam")) { pizza = new ClamPizza(); } else if(type.equals("veggie")) { pizza = new VeggiePizza(); } return pizza; } }
public abstract class Pizza { public void prepare(){ } public void bake(){ } public void cut(){ } public void box(){ } }
在这里我们将制造pizza的工厂SimplePizzaFactory注入到PizzaStore的构造器中,方便PizzaStore的方法来制造pizza。另外每一个具体的pizza子类都继承自Pizza类,这样可以使得系统更有弹性。
public abstract class CarFactory { public abstract Car createCar(String type); }
具体创建者类有2个:
public class NIOCarFactory extends CarFactory { @Override public Car createCar(String type) { if(type.equals("es6")) { return new NIOES6(); } else if(type.equals("es8")) { return new NIOES8(); } return null; } }
public class XPFactory extends CarFactory{ @Override public Car createCar(String type) { if(type.equals("p7")) { return new XP7(); } else if(type.equals("p9")) { return new XP9(); } return null; } }
在具体的工厂中根据不同的type创建对应的小汽车。
抽象产品类:
public abstract class Car { }
具体产品类(这里只写一个,其它类似):
public class NIOES8 extends Car{ @Override public String toString() { return "NIO ES8"; } }
在工厂方法模式中,客户端不需知道具体产品类的类名,只需知道创建具体产品的工厂类;对于抽象工厂类,只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象。这个模式符合“依赖倒置”原则,即要依赖抽象,不要依赖具体类。这个原则表明:不能让高层组件依赖低层组件,而且不敢高层或低层组件,两者都应该依赖抽象。在上面的例子中,CarFactory是高层组件,Car的具体子类则是低层组件。二者都依赖于Car这个抽象。
依赖倒置原则的指导方针:
(1)变量不可以持有具体类的引用。
(2)不要让类派生自具体类。
(3)不要覆盖基类中已实现的方法。
public abstract class ComputerStore { abstract Computer sell(String type); }
public abstract class Computer { Mouse mouse; KeyBoard keyBoard; }在Computer类中包含多个组件,如鼠标Mouse和Keyboard键盘,并且这些组件各自含有不同的牌子。因此如果使用工厂方法模式为每一个组件都设置一个工厂那么会创建出很多个工厂类,在这种情况下可以使用抽象工厂模式,即工厂中创建产品族。
public abstract class ComputerIngredientFactory { abstract Mouse createMouse(String type); abstract KeyBoard createKeyBoard(String type); }
public class LogitechIngredientFactory extends ComputerIngredientFactory{ @Override Mouse createMouse(String type) { return new LogitechMouse(); } @Override KeyBoard createKeyBoard(String type) { return new LogitechKeyBoard(); } }
可以看到在ComputerIngredientFactory接口中提供了创建Mouse和KeyBoard类的接口,然后在LogitechIngredientFactory中对其进行了实现。注意:LogitechMouse类和LogitechKeyBoard类分别继承自Mouse和KeyBoard抽象类。
在使用时,将创建的工厂注入到具体类中,从而获取到工厂生产的不同组件。
public class ThinkPadComputerStore extends ComputerStore{ @Override Computer sell(String type) { ComputerIngredientFactory factory = new LogitechIngredientFactory(); if(type.equals("x1")) { return new ThinkPadComputer(factory); } return null; } }
public class ThinkPadComputer extends Computer{ public ThinkPadComputer(ComputerIngredientFactory factory) { this.mouse = factory.createMouse(""); this.keyBoard = factory.createKeyBoard(""); } }
可以看出,抽象工厂的方法经常以工厂方法的方式实现,工厂内的每一个方法都负责创建一个具体产品,同时利用抽象工厂的子类来提供这些具体子类的实现。