哇塞码农设计模式系列 -- 抽象工厂模式

更新于2024-11-05 08:01:0013 分钟6 千字2331415500
摘要

抽象工厂模式

抽象工厂模式是一种创建型设计模式,用于提供一个接口以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。这种模式通过提供一个抽象类或接口来定义一组工厂方法,每个工厂方法用于创建不同种类的对象。抽象工厂模式可以帮助客户端代码与具体类的实现分离,从而使系统更加灵活、可扩展和可维护。

UML类图

以下是类图的各个部分及其功能的介绍:

  1. 抽象工厂(AbstractFactory)
    • 这是一个接口或抽象类,定义了创建一组相关产品对象的方法。
    • 功能:提供了一种统一的方式来创建一系列相关或相互依赖的产品对象,而无需指定它们具体的类。
  2. 具体工厂(ConcreteFactory1, ConcreteFactory2)
    • 这些类实现了抽象工厂接口,负责创建具体的产品对象。
    • 功能:实现了抽象工厂中定义的方法,每个具体工厂对应一组相关的产品对象。
  3. 抽象产品(AbstractProductA, AbstractProductB)
    • 这些是产品对象的接口或抽象类,定义了产品对象的通用行为。
    • 功能:提供了一种统一的方式来访问产品对象的功能,客户端代码通过这些接口来使用产品对象。
  4. 具体产品(ConcreteProductA1, ConcreteProductA2, ConcreteProductB1, ConcreteProductB2)
    • 这些类实现了抽象产品接口或继承了抽象产品抽象类,表示具体的产品对象。
    • 功能:实现了具体产品的特定功能,具体工厂根据需要创建这些产品对象并返回给客户端代码使用。

在抽象工厂模式中,抽象工厂负责定义创建产品对象的接口,具体工厂实现这个接口以创建具体的产品对象。这样,客户端代码与具体产品的实现分离,客户端只需要通过抽象工厂接口来创建产品对象,并使用这些产品对象的通用接口来进行操作,从而实现了系统的解耦和灵活性。

PlantUML Image

Java示例

// 抽象产品A
interface AbstractProductA {
    void operationA();
}

// 具体产品A1
class ConcreteProductA1 implements AbstractProductA {
    public void operationA() {
        System.out.println("ConcreteProductA1 operationA");
    }
}

// 具体产品A2
class ConcreteProductA2 implements AbstractProductA {
    public void operationA() {
        System.out.println("ConcreteProductA2 operationA");
    }
}

// 抽象产品B
interface AbstractProductB {
    void operationB();
}

// 具体产品B1
class ConcreteProductB1 implements AbstractProductB {
    public void operationB() {
        System.out.println("ConcreteProductB1 operationB");
    }
}

// 具体产品B2
class ConcreteProductB2 implements AbstractProductB {
    public void operationB() {
        System.out.println("ConcreteProductB2 operationB");
    }
}

// 抽象工厂
interface AbstractFactory {
    AbstractProductA createProductA();
    AbstractProductB createProductB();
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA1();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
    public AbstractProductA createProductA() {
        return new ConcreteProductA2();
    }

    public AbstractProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();

        productA1.operationA();
        productB1.operationB();

        AbstractFactory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();

        productA2.operationA();
        productB2.operationB();
    }
}

适用场景

抽象工厂模式通常在以下情况下适用:

  1. 需要创建一系列相关或相互依赖的产品对象:如果系统中的一组对象之间存在关联或依赖关系,并且需要以一种统一的方式来创建这些对象,那么抽象工厂模式是一个很好的选择。
  2. 希望将产品对象的创建与客户端代码解耦:使用抽象工厂模式可以将具体产品的实现细节隐藏在具体工厂内部,客户端代码只需要与抽象工厂接口进行交互,而不需要知道具体产品的类名或实现细节。
  3. 需要满足一定的产品族约束:有时候系统需要确保一组创建出来的产品对象是相互匹配或配套的,例如在某个操作系统下,按钮、文本框、滚动条等 GUI 组件的风格应该保持一致。抽象工厂模式可以确保同一个具体工厂创建的产品对象之间具有一致性。
  4. 需要支持产品对象的扩展:通过抽象工厂模式,可以轻松地添加新的产品族,只需扩展抽象工厂及其对应的具体工厂和产品类即可,而不需要修改现有代码。

总的来说,抽象工厂模式适用于那些需要在运行时选择创建一组相关对象,并希望将对象创建的过程与客户端代码解耦的情况。

反射与依赖注入优化

// TODO 待补充

// 定义产品接口
interface Product {
    void operation();
}

// 具体产品类1
class ConcreteProduct1 implements Product {
    public void operation() {
        System.out.println("ConcreteProduct1 operation");
    }
}

// 具体产品类2
class ConcreteProduct2 implements Product {
    public void operation() {
        System.out.println("ConcreteProduct2 operation");
    }
}

// 定义工厂接口
interface Factory {
    Product createProduct();
}

// 具体工厂类,接受一个产品列表作为参数
class ConcreteFactory implements Factory {
    private List<Class<? extends Product>> productClasses;

    public ConcreteFactory(List<Class<? extends Product>> productClasses) {
        this.productClasses = productClasses;
    }

    public Product createProduct() {
        // 遍历产品类列表,实例化第一个找到的产品类
        for (Class<? extends Product> productClass : productClasses) {
            try {
                return productClass.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

public class Client {
    public static void main(String[] args) {
        // 初始化产品列表
        List<Class<? extends Product>> productClasses = new ArrayList<>();
        productClasses.add(ConcreteProduct1.class);
        productClasses.add(ConcreteProduct2.class);

        // 创建工厂实例并传入产品列表
        Factory factory = new ConcreteFactory(productClasses);

        // 使用工厂创建产品对象
        Product product = factory.createProduct();

        // 调用产品对象的方法
        product.operation();
    }
}

评论区

你认为这篇文章怎么样?
  • great
    0
  • happy
    0
  • doubt
    0
  • boring
    0
  • bad
    0

0/2048