2) Abstract Factory Pattern
类别:
Creational Pattern
问题/动机:
如何创建一套父类的问题
情形一:混淆,且不能察觉
// 下面这个方法本来是要建造一辆宝马汽车,但是因为零部件太多,粗心大意误用了奔驰的零件。 public Car createBMWCar(){ Part1 p1 = new com.bmw.Part1(); [...] Part10000 p10000 = new com.benz.Part10000(); [...] }
情形二:可完全避免混淆问题
import com.bmw.BMWFactory; [...] // 下面使用的是一个工厂,因为只引用了宝马工厂,所以不能可能出现奔驰的零件。 public Car createBMWCar(){ Part1 p1 = BMWFactory.getPart1(); [...] Part10000 p10000 = BMWFactory.getPart10000(); [...] }
方案:
https://en.wikipedia.org/wiki/Abstract_factory_pattern
示例:
public class AbstractFactoryPatternDemo { public static void main(String[] args) { GUIFactory guiFactory; Box box; Button button; // situation one: guiFactory = new WinFactory(); box = guiFactory.createBox(); box.paint(); button = guiFactory.createButton(); button.paint(); // situation two: guiFactory = new MacOSFactory(); box = guiFactory.createBox(); box.paint(); button = guiFactory.createButton(); button.paint(); } } // GUI Graphical User Interface // https://docs.unity3d.com/ScriptReference/GUI.Button.html // https://docs.unity3d.com/ScriptReference/GUI.Box.html interface Button { void paint(); } interface Box { void paint(); } interface GUIFactory { public Button createButton(); public Box createBox(); } class WinFactory implements GUIFactory { @Override public Button createButton() { return new WinButton(); } @Override public Box createBox() { return new WinBox(); } } class MacOSFactory implements GUIFactory { @Override public Button createButton() { return new MacOSButton(); } @Override public Box createBox() { return new MacOSBox(); } } class WinButton implements Button { @Override public void paint() { System.out.println("WinButton"); } } class MacOSButton implements Button { @Override public void paint() { System.out.println("macOS button"); } } class WinBox implements Box { @Override public void paint() { System.out.println("WinBox"); } } class MacOSBox implements Box { @Override public void paint() { System.out.println("macOS box"); } }
WinBox WinButton macOS box macOS button
分析:
抽象工厂模式具备工厂模式的所有优缺点
额外的,依据不同环境得到具体工厂,代码持有父接口(向上转型),可通过注入获得具体工厂类而代码无需变动
不足:(
如果抽象类需要做改动,牵扯到所有子类
优化:)
无