1.介绍


抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定其具体类。这种模式属于工厂模式的一种扩展,它通过引入抽象层来实现工厂方法的组合,从而使得客户端能够使用抽象的接口创建一组相关的产品对象。

2.定义


抽象工厂模式定义了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

3. 主要作用


抽象工厂模式允许你定义一个创建对象的接口,这些对象之间有关联或依赖关系,而具体的创建逻辑由实现了该接口的具体工厂类负责。这样一来,客户端只需与抽象工厂及其产品接口交互,而不用关心具体的产品实现细节,从而达到了解耦的效果。

到这里你是不是有疑惑,这TM和工厂方法模式有什么区别啊!不急,继续往下看👇

4.解决的问题


  • 客户端代码与具体工厂类的耦合问题,客户端通过抽象接口与具体工厂分离。
  • 系统扩展时可以灵活添加新的产品族,无需修改现有代码。

5.模式原理


包含角色:

  • 抽象工厂(Abstract Factory):定义创建一组产品的接口,每个方法对应一种产品。
  • 具体工厂(Concrete Factory):实现抽象工厂接口,负责创建一组具体产品。
  • 抽象产品(Abstract Product):定义产品的接口,描述产品的公共方法。
  • 具体产品(Concrete Product):实现抽象产品接口,具体产品之间属于同一产品族。

UML类图:

技术成神之路:设计模式(五)抽象工厂模式_UI

代码示例:

// 抽象产品:按钮接口
public interface Button {
    void display();
}

// 具体产品:安卓风格按钮
public class AndroidButton implements Button {
    @Override
    public void display() {
        System.out.println("显示安卓风格按钮");
    }
}

// 具体产品:iOS风格按钮
public class IOSButton implements Button {
    @Override
    public void display() {
        System.out.println("显示iOS风格按钮");
    }
}

// 抽象工厂:UI组件工厂
public interface UIFactory {
    Button createButton();
}

// 具体工厂:安卓风格UI组件工厂
public class AndroidUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new AndroidButton();
    }
}

// 具体工厂:iOS风格UI组件工厂
public class IOSUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new IOSButton();
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        // 使用安卓风格工厂创建按钮
        UIFactory androidFactory = new AndroidUIFactory();
        Button androidButton = androidFactory.createButton();
        androidButton.display();

        // 使用iOS风格工厂创建按钮
        UIFactory iosFactory = new IOSUIFactory();
        Button iosButton = iosFactory.createButton();
        iosButton.display();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.

打印:

显示安卓风格按钮
显示iOS风格按钮
  • 1.
  • 2.

🤦♀️此时的你: emm... 和工厂方法模式有一点不同了,但是从示例代码看上去区别不是很大吗,还是没搞懂。

🤦♂️我: 再来个示例吧,保证你豁然开朗✨

拓展示例:加入更多的产品

定义新的抽象产品

// 抽象产品:文本框接口
public interface TextBox {
    void display();
}
  • 1.
  • 2.
  • 3.
  • 4.

定义新的具体产品

// 具体产品:安卓风格文本框
public class AndroidTextBox implements TextBox {
    @Override
    public void display() {
        System.out.println("显示安卓风格文本框");
    }
}

// 具体产品:iOS风格文本框
public class IOSTextBox implements TextBox {
    @Override
    public void display() {
        System.out.println("显示iOS风格文本框");
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

更新抽象工厂接口

// 抽象工厂:UI组件工厂
public interface UIFactory {
    Button createButton();
    TextBox createTextBox();
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

更新具体工厂

// 具体工厂:安卓风格UI组件工厂
public class AndroidUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new AndroidButton();
    }

    @Override
    public TextBox createTextBox() {
        return new AndroidTextBox();
    }
}

// 具体工厂:iOS风格UI组件工厂
public class IOSUIFactory implements UIFactory {
    @Override
    public Button createButton() {
        return new IOSButton();
    }

    @Override
    public TextBox createTextBox() {
        return new IOSTextBox();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

调用

public class Client {
    public static void main(String[] args) {
        // 使用安卓风格工厂创建UI组件
        UIFactory androidFactory = new AndroidUIFactory();
        Button androidButton = androidFactory.createButton();
        TextBox androidTextBox = androidFactory.createTextBox();
        androidButton.display();
        androidTextBox.display();

        // 使用iOS风格工厂创建UI组件
        UIFactory iosFactory = new IOSUIFactory();
        Button iosButton = iosFactory.createButton();
        TextBox iosTextBox = iosFactory.createTextBox();
        iosButton.display();
        iosTextBox.display();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

打印

显示安卓风格按钮
显示安卓风格文本框
显示iOS风格按钮
显示iOS风格文本框
  • 1.
  • 2.
  • 3.
  • 4.

🤦♂️我: 这下区别更大了吧!他们的区别就在于:抽象工厂模式用于创建多个产品族的对象。每个具体工厂都能生产一整组相关的产品。 工厂方法模式用于创建一种产品,但由子类决定要实例化的具体产品。

🤦♀️你: 搜嘎 搜嘎,看来还是有区别的嘛😆

🤦♂️我: 思维发散一下,在安卓中不同的系统主题有其对应的UI控件风格,你猜猜它使用的是什么设计模式...

6.优缺点


优点:

  • 分离了具体的产品实现和客户端代码,客户端通过抽象接口操作具体产品。
  • 符合开闭原则,易于扩展,增加新的产品族很方便。

缺点:

  • 增加新的产品等级结构比较复杂,需要修改抽象工厂及所有的具体工厂。

7.应用场景


  1. 需要创建一系列相关或依赖的对象:例如,创建跨平台的UI组件(按钮、文本框等),每个平台都有一套相应的实现。
  2. 系统的产品族设计:例如,创建不同主题的UI组件(暗黑主题、明亮主题等),确保组件的一致性。
  3. 客户端不需要知道具体产品的创建细节:例如,通过配置文件决定使用哪个具体工厂。

🤔一般应用场景都是大型项目上,实现起来略复杂,我还是喜欢简单工厂模式,哈哈哈

8.总结


抽象工厂模式是一种创建型设计模式,它允许客户端创建一系列相关或相互依赖的对象,而无需指定它们具体的类。通过定义一组抽象产品接口和相应的具体工厂,系统能够灵活地支持多种产品族,并且保证产品族的一致性。尽管这种模式增加了系统的复杂性,但它在需要创建相关对象集的场景中非常有用。

还是那句话:选择适合自己程序的设计模式,不要为了设计而设计!