Java设计模式 四 抽象工厂模式 (Abstract Factory Pattern)

抽象工厂模式 (Abstract Factory Pattern) 是一种创建型设计模式,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。抽象工厂模式为产品族的创建提供了一个接口,其核心在于解决“产品族的扩展”和“客户端与具体工厂的解耦”。

1. 模式结构

抽象工厂模式的参与者包括以下角色:

  • AbstractFactory(抽象工厂): 定义创建一系列相关对象的接口。
  • ConcreteFactory(具体工厂): 实现抽象工厂的接口,负责创建具体产品。
  • AbstractProduct(抽象产品): 定义产品的通用接口。
  • ConcreteProduct(具体产品): 实现具体的产品接口。
  • Client(客户端): 通过抽象工厂接口使用产品,而不需要直接依赖具体产品类。

2. 抽象工厂模式的优点

  • 产品族一致性: 确保一个工厂生产的产品是同一个系列的,避免客户端混用不同系列的产品。
  • 易于扩展: 增加新的产品族时,只需要增加新的具体工厂和产品类,符合开闭原则。
  • 解耦客户端和产品: 客户端通过抽象接口使用工厂和产品,不需要关心具体实现。

3. 抽象工厂模式的缺点

  • 复杂性增加: 增加产品族需要添加多个类,可能使系统更加复杂。
  • 不支持新产品的扩展: 如果需要向已有的产品族中添加新产品,需要修改抽象工厂接口及其所有具体工厂实现,违背开闭原则。

4. 实现步骤

1) 定义抽象产品接口

定义每种产品的抽象接口,描述其功能。

// 抽象产品A
public interface ProductA {
    void use();
}

// 抽象产品B
public interface ProductB {
    void display();
}
2) 实现具体产品类

不同产品族中具体产品的实现。

// 产品族1的具体产品A
public class ConcreteProductA1 implements ProductA {
    @Override
    public void use() {
        System.out.println("Using ProductA1");
    }
}

// 产品族1的具体产品B
public class ConcreteProductB1 implements ProductB {
    @Override
    public void display() {
        System.out.println("Displaying ProductB1");
    }
}

// 产品族2的具体产品A
public class ConcreteProductA2 implements ProductA {
    @Override
    public void use() {
        System.out.println("Using ProductA2");
    }
}

// 产品族2的具体产品B
public class ConcreteProductB2 implements ProductB {
    @Override
    public void display() {
        System.out.println("Displaying ProductB2");
    }
}
3) 定义抽象工厂接口

抽象工厂定义了创建每种产品的方法。

public interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}
4) 实现具体工厂类

具体工厂实现了抽象工厂接口,负责实例化具体产品。

// 产品族1的工厂
public class ConcreteFactory1 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 产品族2的工厂
public class ConcreteFactory2 implements AbstractFactory {
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    @Override
    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}
5) 客户端代码

客户端通过抽象工厂接口创建产品,而无需关心具体实现。

public class Client {
    public static void main(String[] args) {
        // 使用工厂1创建产品族1
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.use();  // 输出: Using ProductA1
        productB1.display();  // 输出: Displaying ProductB1

        // 使用工厂2创建产品族2
        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.use();  // 输出: Using ProductA2
        productB2.display();  // 输出: Displaying ProductB2
    }
}

5. 使用场景

  1. 产品有多个系列,且系列内的产品一起使用时:
    比如 GUI 系统中,Windows 和 MacOS 的按钮、文本框等组件需要成套使用。

  2. 需要向客户端隐藏产品的具体实现时:
    客户端只关心工厂和产品的接口,而无需了解具体产品类。

  3. 需要保证产品族的一致性时:
    确保客户端不会意外混用不同产品族的对象。


6. 抽象工厂模式的优缺点对比

优点:
  • 产品族一致性: 能够保证同一工厂创建的产品是同一个系列的。
  • 扩展产品族容易: 增加新的产品族时,只需添加新的工厂类,不需要修改现有代码。
缺点:
  • 增加新产品困难: 如果需要在产品族中添加新产品,必须修改抽象工厂接口和所有具体工厂类,不符合开闭原则。
  • 系统复杂度提高: 随着产品族的增加,类的数量和系统复杂度也会增加。

7. 与工厂方法模式的比较

特性工厂方法模式抽象工厂模式
关注点创建单一产品创建一组相关产品
新增产品新增产品时,需要新增一个具体工厂类新增产品族时,需要新增具体工厂类
新增产品类别支持新增产品类别,扩展性更好新增产品类别需要修改工厂接口,扩展性较差
复杂度相对较低较高,涉及多个产品类和工厂类

8. 总结

抽象工厂模式适用于创建一系列相关或相互依赖的对象,同时能够保证产品族的完整性和一致性。在实际开发中,抽象工厂模式广泛应用于 GUI 框架、数据库访问层等场景。
当你需要为不同的产品族提供一套通用的创建逻辑时,抽象工厂模式是一个非常适合的选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十方来财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值