工厂模式 与 抽象工厂模式 的区别

工厂模式:

java 复制代码
// 抽象产品接口
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 是抽象产品接口,ConcreteProductAConcreteProductB 是具体的产品类。Creator 是抽象工厂类,ConcreteCreatorAConcreteCreatorB 是具体的工厂类,分别生产不同的产品。在场景类中,通过具体的工厂来创建不同的产品,而无需直接涉及具体产品的实现类。这就是工厂方法模式的正确用法。

抽象工厂模式:

java 复制代码
// 抽象产品接口
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 是抽象工厂接口,ConcreteFactory1ConcreteFactory2 是具体工厂类,分别生产不同系列的产品。每个具体工厂类实现了创建一组相关产品的方法。这就是抽象工厂模式的示例。

区别:

抽象工厂模式(Abstract Factory Pattern)和工厂方法模式(Factory Method Pattern)是两种不同的设计模式,它们都属于创建型模式,用于创建对象。它们之间的区别在于抽象程度和用途。

  1. 抽象工厂模式

    • 抽象工厂模式用于创建一组相关或相互依赖的对象,这些对象通常属于不同的产品族。
    • 它包含一个抽象工厂接口,该接口声明了一组用于创建不同类型产品的抽象方法。每个具体工厂类实现了这些方法以创建特定产品族的对象。
    • 抽象工厂模式强调创建一组对象,通常涉及多个产品接口和多个产品实现类。
  2. 工厂方法模式

    • 工厂方法模式用于创建单一对象,但是通过子类来决定实例化哪个类。
    • 它包含一个抽象工厂基类(接口或抽象类),该基类声明了一个用于创建对象的抽象方法。每个具体工厂子类实现这个方法以返回特定的产品对象。
    • 工厂方法模式强调创建单一对象,每个工厂子类负责创建一种产品。

总结:

抽象工厂模式关注于一组相互关联的产品,而工厂方法模式关注于单一产品。抽象工厂模式的实现可能比较复杂,涉及多个产品族,而工厂方法模式通常相对简单,每个子类只负责一个产品。选择哪个模式取决于需求的复杂性和结构的设计。

抽象工厂模式在工厂模式的基础上扩展了一个维度,不仅关注单一产品的创建,还关注一组相关或相互依赖的产品族的创建。这些产品族通常在业务逻辑上有关联,它们可能共同构成一个完整的功能。

缺点总结:

在抽象工厂模式中,如果你想要增加一个新的产品,比如产品C,你需要在抽象工厂接口(或抽象类)中添加一个新的方法来创建该产品。然后,所有的具体工厂类都必须实现这个新方法,为产品C提供实现。这会导致两个问题:

  1. 修改抽象类或接口: 在这个例子中,你需要在AbstractCreator中增加一个createProductC()方法,并且ConcreteFactory1 和ConcreteFactory2都必须实现这个方法。这违反了开闭原则,即系统应该对扩展开放,对修改关闭。

  2. 影响已有代码: 增加新方法会影响到所有已经实现了该抽象工厂的具体工厂类,即ConcreteFactory1 和ConcreteFactory2。这可能会导致许多现有的代码需要修改,因此它们与这个变化产生了依赖关系,即所谓的"有毒代码"。

这种情况下,每次需要增加一个新的产品时,都会引发一系列的修改,从而导致系统的脆弱性和不稳定性。这就是抽象工厂模式的一个局限性,特别是当产品族的变化比较频繁时,扩展性不如其他设计模式。

这也是为什么有时候推荐使用工厂方法模式,因为它对于新增产品更具有弹性,不会对已有的代码造成较大的影响。但抽象工厂模式的优势在于它能够同时创建一组相关的产品,适用于需要创建一组具有特定关联性的对象的情况。

但是也有优点,在添加新的产品族时,只需要新增对应的产品接口和实现,而不需要修改已有的工厂类和产品类。这符合开闭原则,允许易于扩展而不影响现有代码。

相关推荐
awonw13 分钟前
[python][flask]Flask-Principal 使用详解
开发语言·python·flask
潼心1412o21 分钟前
C语言(长期更新)第6讲:函数
c语言·开发语言
微笑听雨28 分钟前
Java 设计模式之单例模式(详细解析)
java·后端
微笑听雨28 分钟前
【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
java·后端
猫猫的小茶馆1 小时前
【STM32】FreeRTOS 任务的删除(三)
java·linux·stm32·单片机·嵌入式硬件·mcu·51单片机
天天摸鱼的java工程师1 小时前
🔧 MySQL 索引的设计原则有哪些?【原理 + 业务场景实战】
java·后端·面试
空影学Java1 小时前
Day44 Java数组08 冒泡排序
java
程序员编程指南2 小时前
Qt 与 WebService 交互开发
c语言·开发语言·c++·qt·交互
追风少年浪子彦2 小时前
mybatis-plus实体类主键生成策略
java·数据库·spring·mybatis·mybatis-plus
赵英英俊2 小时前
Python day26
开发语言·python