抽象工厂模式也是23种设计模式中的一种,它隶属于创建性模式,与之前简单工厂,工厂方法设计模式相比,抽象工厂要复杂的多。
简单工厂模式违反了开闭原则,工厂方法模式生产具有产品等级及产品簇的产品会十分复杂,每生产一个新产品即要创建一个新产品类和一个新工厂类。
抽象工厂设计模式结合了前两种模式的优缺点,但不代表它没有缺点,因为它也违反了 开闭原则,新增一个产品等级的时候,抽象工厂接口及所有的工厂类都要进行修改。但在产品簇中新增一个新产品时,我们只需再添加一个新的工厂类即可。
下面还是以汽车例子做出说明,丰田不仅生产丰田车,也生产雷克萨斯,这就是它的同一产品等级的产物。而每一个产品等级下又对应多个车型,例如丰田有皇冠,有凯美瑞,有卡罗拉。雷克萨斯有IS,ES,GS等各个产品,这称为产品簇。
public class AbstractFactoryDemo { interface Car { void run(); void stop(); void brand(); } static class ToyoTaCar implements Car { @Override public void run() { } @Override public void stop() { } @Override public void brand() { System.out.println("我的品牌是:丰田"); } } static class LexusCar implements Car { @Override public void run() { } @Override public void stop() { } @Override public void brand() { System.out.println("我的品牌是:雷克萨斯"); } } /** * B级车凯美瑞 */ static class Camry extends ToyoTaCar { @Override public void run() { System.out.println("凯美瑞启动"); } @Override public void stop() { System.out.println("凯美瑞停止"); } } /** * B级车IS200 */ static class IS200 extends LexusCar { @Override public void run() { System.out.println("IS200启动"); } @Override public void stop() { System.out.println("IS200停止"); } } /** * C级车丰田皇冠 */ static class Crown extends ToyoTaCar { @Override public void run() { System.out.println("Crown启动"); } @Override public void stop() { System.out.println("Crown停止"); } } /** * C级车ES300 */ static class ES300 extends LexusCar { @Override public void run() { System.out.println("ES300启动"); } @Override public void stop() { System.out.println("ES300停止"); } } interface CarFactory { ToyoTaCar factoryToyoTa(); LexusCar factoryLexus(); } /** * B级车对应产品等级生产工厂 */ static class BFactory implements CarFactory { @Override public ToyoTaCar factoryToyoTa() { return new Camry(); } @Override public LexusCar factoryLexus() { return new IS200(); } } static class CFactory implements CarFactory { @Override public ToyoTaCar factoryToyoTa() { return new Crown(); } @Override public LexusCar factoryLexus() { return new ES300(); } } public static void main(String[] args) { CarFactory carFactory = new BFactory(); Car car1 = carFactory.factoryLexus(); car1.run(); car1.stop(); car1.brand(); System.out.println("----------------"); Car car2 = carFactory.factoryToyoTa(); car2.run(); car2.stop(); car2.brand(); } }
如果我想在丰田产品等级下添加A级车卡罗拉,在雷克萨斯产品等级下添加GS车型。我们只需创建一个新的工厂,分别实现生产toyota汽车和lexus汽车的接口即可,不需改动CarFactory,这是符合开闭原则的。但是如果我们要在丰田公司添加英菲尼迪这个产品等级。我们便要在CarFactory中添加生产英菲尼迪汽车的接口,那所有实现该接口的工厂类都需要修改,这显然违反了开闭原则。
这一概念叫开闭原则的倾斜性