抽象工厂模式

抽象工厂模式

  • by Head First 设计模式

    抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。 简而言之,抽象工厂可以创建一群对象,而不单单只创建一种对象。这是抽象工厂和工厂方法的区别。

  • by Dive into Design Patterns

    Abstract Factory is a creation(al) design pattern that lets you produce families of related objects without specifying their concrete classes.

UML简图 #

classDiagram
class AbstractFactory {
  << Abstract >>
  createProductA() ProductA
  createProductB() ProductB
  otherMethod()
}

ConcreteFactoryA --|> AbstractFactory
class ConcreteFactoryA{
  createProductA() ProductA
  createProductB() ProductB
}
ConcreteFactoryB --|> AbstractFactory
class ConcreteFactoryB {
  createProductA() ProductA
  createProductB() ProductB
}

ConcreteFactoryA <.. ProductA
ConcreteFactoryA <.. ProductB
class ProductA {
  << Interface >>
}

ProductA <|.. ConcreteProductA
class ConcreteProductA

ConcreteFactoryB <.. ProductA
ConcreteFactoryB <.. ProductB
class ProductB {
  << Interface >>
}
ProductB <|.. ConcreteProductB
class ConcreteProductB

AbstractFactory <..* Client
class Client {
  -AbstractFactory absFactory
  +Client(AbstractFactory f) Client
  +otherMethod()
}

设计原则 #

  • 针对接口编程,而不是针对实现编程
  • 多用组合,少用继承
  • 为交互对象之间的松耦合而努力
  • 类应该对拓展开放,而对修改关闭 (开放-关闭原则)
  • 依赖抽象,而不依赖具体类 (依赖倒置原则)

示例代码 #

本示例和 工厂方法模式的代码类似,不过多添加了一个产品类型,将其变成一个抽象工厂。注意两个模式之间的区别。

定义产品 #

定义了2个产品接口——按扭复选框,假如2个产品在Win和Mac平台上有不同的实现细节。那么就可以定义出一下的产品及其实现:

产品——按扭:

 1public interface Button2 {
 2
 3    void paint();
 4}
 5
 6public class Button2Mac implements Button2 {
 7    @Override
 8    public void paint() {
 9        System.out.println("mac: button click");
10    }
11}
12
13public class Button2Win implements Button2 {
14    @Override
15    public void paint() {
16        System.out.println("win: button click");
17    }
18}

产品——复选框:

 1public interface CheckBox {
 2
 3    void paint();
 4}
 5
 6public class CheckBoxMac implements CheckBox{
 7    @Override
 8    public void paint() {
 9        System.out.println("mac: box check");
10    }
11}
12
13public class CheckBoxWin implements CheckBox{
14    @Override
15    public void paint() {
16        System.out.println("win: box check");
17    }
18}

抽象工厂及其实现 #

和工厂方法不同,抽象工厂方法(接口)定义了一组创建对象的方法,而由它的实现决定每个具体对象的实现。

 1public interface GUIFactory {
 2
 3    Button2 createButton();
 4    CheckBox createCheckBox();
 5}
 6
 7public class GUIFactoryMac implements GUIFactory{
 8    @Override
 9    public Button2 createButton() {
10        return new Button2Mac();
11    }
12
13    @Override
14    public CheckBox createCheckBox() {
15        return new CheckBoxMac();
16    }
17}
18
19public class GUIFactoryWin implements GUIFactory{
20    @Override
21    public Button2 createButton() {
22        return new Button2Win();
23    }
24
25    @Override
26    public CheckBox createCheckBox() {
27        return new CheckBoxWin();
28    }
29}

测试类 #

 1public class TestAbsFactory {
 2    /**
 3     * 依赖倒置:客户依赖抽象,而不是依赖具体类。
 4     */
 5    static GUIFactory factory;
 6    static Button2 button2;
 7    static CheckBox checkBox;
 8
 9    public static void main(String[] args) {
10        String os = "mac";
11        if (args.length != 0) os = args[0];
12        init(os);
13        button2 = factory.createButton();
14        checkBox = factory.createCheckBox();
15        button2.paint();
16        checkBox.paint();
17    }
18
19    public static void init(String os) {
20        System.setProperty("current.os", os);
21        if (System.getProperty("current.os").equals("windows"))
22            factory = new GUIFactoryWin();
23        else factory = new GUIFactoryMac();
24    }
25}
26///:~
27//mac: button click
28//mac: box check
29//

与工厂模式的区别 #

Generated by Gemini 1.5-flash, revised

工厂 #

  • 核心思想: 提供一个创建对象的接口,但由子类决定实例化哪个类。
  • 特点: 简单直接,适合创建单一类型的对象。
  • 结构: 通常包含一个抽象工厂类(接口)和多个具体工厂类,每个具体工厂类负责创建特定类型对象的实例。

抽象工厂 #

  • 核心思想: 提供一个创建一系列相关或依赖对象的接口,但无需指定具体类。
  • 特点: 更灵活,适合创建多个相关对象,例如,一个工厂创建多个类型的产品。
  • 结构: 包含一个抽象工厂类(接口)、多个具体工厂类和多个抽象产品类以及多个具体产品类。每个具体工厂类负责创建一组特定类型产品对象的实例。

区别总结 #

特性工厂模式抽象工厂模式
核心目的创建单一类型的对象创建多个相关或依赖对象的系列
复杂程度相对简单相对复杂
灵活性较低较高
应用场景创建单一类型的对象时需要创建多个相关或依赖对象的系列时
实例创建汽车时,工厂模式可以创建一辆汽车创建汽车时,抽象工厂模式可以创建一辆汽车和一个发动机

简单来说,工厂模式就像一个简单的工具,只负责生产一种特定类型的产品;而抽象工厂模式就像一个完整的生产线,可以生产多种相关产品的系列。

一些补充的话

  • 所有的工厂都是用封装来创建对象。
  • 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
  • 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露的方法中。
  • 所有工厂模式通过减少应用程序和具体类之间的依赖,而促进松耦合。
  • 工厂方法允许将类的实例化延迟到子类进行。
  • 抽象工厂创建相关的对象家族,而不需要依赖它的具体类。