- // 抽象产品接口
- interface Product {
- void showInfo();
- }
-
- // 具体产品A
- class ConcreteProductA implements Product {
- @Override
- public void showInfo() {
- System.out.println("This is Product A");
- }
- }
-
- // 具体产品B
- class ConcreteProductB implements Product {
- @Override
- public void showInfo() {
- System.out.println("This is Product B");
- }
- }
-
- // 抽象工厂类
- abstract class Creator {
- abstract Product createProduct();
- }
-
- // 具体工厂A,生产产品A
- class ConcreteCreatorA extends Creator {
- @Override
- Product createProduct() {
- return new ConcreteProductA();
- }
- }
-
- // 具体工厂B,生产产品B
- class ConcreteCreatorB extends Creator {
- @Override
- Product createProduct() {
- return new ConcreteProductB();
- }
- }
-
- public class FactoryMethodExample {
- public static void main(String[] args) {
- Creator creatorA = new ConcreteCreatorA();
- Product productA = creatorA.createProduct();
- productA.showInfo();
-
- Creator creatorB = new ConcreteCreatorB();
- Product productB = creatorB.createProduct();
- productB.showInfo();
- }
- }
在这个示例中,Product
是抽象产品接口,ConcreteProductA
和 ConcreteProductB
是具体的产品类。Creator
是抽象工厂类,ConcreteCreatorA
和 ConcreteCreatorB
是具体的工厂类,分别生产不同的产品。在场景类中,通过具体的工厂来创建不同的产品,而无需直接涉及具体产品的实现类。这就是工厂方法模式的正确用法。
- // 抽象产品接口
- interface ProductA {
- void showInfo();
- }
-
- // 具体产品A1
- class ConcreteProductA1 implements ProductA {
- @Override
- public void showInfo() {
- System.out.println("This is Product A1");
- }
- }
-
- // 具体产品A2
- class ConcreteProductA2 implements ProductA {
- @Override
- public void showInfo() {
- System.out.println("This is Product A2");
- }
- }
-
- // 抽象产品接口
- interface ProductB {
- void showInfo();
- }
-
- // 具体产品B1
- class ConcreteProductB1 implements ProductB {
- @Override
- public void showInfo() {
- System.out.println("This is Product B1");
- }
- }
-
- // 具体产品B2
- class ConcreteProductB2 implements ProductB {
- @Override
- public void showInfo() {
- System.out.println("This is Product B2");
- }
- }
-
- // 抽象工厂接口
- interface AbstractFactory {
- ProductA createProductA();
- ProductB createProductB();
- }
-
- // 具体工厂1
- class ConcreteFactory1 implements AbstractFactory {
- @Override
- public ProductA createProductA() {
- return new ConcreteProductA1();
- }
-
- @Override
- public ProductB createProductB() {
- return new ConcreteProductB1();
- }
- }
-
- // 具体工厂2
- class ConcreteFactory2 implements AbstractFactory {
- @Override
- public ProductA createProductA() {
- return new ConcreteProductA2();
- }
-
- @Override
- public ProductB createProductB() {
- return new ConcreteProductB2();
- }
- }
-
- public class AbstractFactoryExample {
- public static void main(String[] args) {
- AbstractFactory factory1 = new ConcreteFactory1();
- ProductA productA1 = factory1.createProductA();
- ProductB productB1 = factory1.createProductB();
- productA1.showInfo();
- productB1.showInfo();
-
- AbstractFactory factory2 = new ConcreteFactory2();
- ProductA productA2 = factory2.createProductA();
- ProductB productB2 = factory2.createProductB();
- productA2.showInfo();
- productB2.showInfo();
- }
- }
在这个示例中,AbstractFactory
是抽象工厂接口,ConcreteFactory1
和 ConcreteFactory2
是具体工厂类,分别生产不同系列的产品。每个具体工厂类实现了创建一组相关产品的方法。这就是抽象工厂模式的示例。
抽象工厂模式(Abstract Factory Pattern)和工厂方法模式(Factory Method Pattern)是两种不同的设计模式,它们都属于创建型模式,用于创建对象。它们之间的区别在于抽象程度和用途。
抽象工厂模式:
工厂方法模式:
抽象工厂模式关注于一组相互关联的产品,而工厂方法模式关注于单一产品。抽象工厂模式的实现可能比较复杂,涉及多个产品族,而工厂方法模式通常相对简单,每个子类只负责一个产品。选择哪个模式取决于需求的复杂性和结构的设计。
抽象工厂模式在工厂模式的基础上扩展了一个维度,不仅关注单一产品的创建,还关注一组相关或相互依赖的产品族的创建。这些产品族通常在业务逻辑上有关联,它们可能共同构成一个完整的功能。
在抽象工厂模式中,如果你想要增加一个新的产品,比如产品C,你需要在抽象工厂接口(或抽象类)中添加一个新的方法来创建该产品。然后,所有的具体工厂类都必须实现这个新方法,为产品C提供实现。这会导致两个问题:
修改抽象类或接口: 在这个例子中,你需要在AbstractCreator
中增加一个createProductC()
方法,并且ConcreteFactory1 和ConcreteFactory2都必须实现这个方法。这违反了开闭原则,即系统应该对扩展开放,对修改关闭。
影响已有代码: 增加新方法会影响到所有已经实现了该抽象工厂的具体工厂类,即ConcreteFactory1 和ConcreteFactory2。这可能会导致许多现有的代码需要修改,因此它们与这个变化产生了依赖关系,即所谓的“有毒代码”。
这种情况下,每次需要增加一个新的产品时,都会引发一系列的修改,从而导致系统的脆弱性和不稳定性。这就是抽象工厂模式的一个局限性,特别是当产品族的变化比较频繁时,扩展性不如其他设计模式。
这也是为什么有时候推荐使用工厂方法模式,因为它对于新增产品更具有弹性,不会对已有的代码造成较大的影响。但抽象工厂模式的优势在于它能够同时创建一组相关的产品,适用于需要创建一组具有特定关联性的对象的情况。
但是也有优点,在添加新的产品族时,只需要新增对应的产品接口和实现,而不需要修改已有的工厂类和产品类。这符合开闭原则,允许易于扩展而不影响现有代码。