抽象工厂模式
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
工厂 #
- 核心思想: 提供一个创建对象的接口,但由子类决定实例化哪个类。
- 特点: 简单直接,适合创建单一类型的对象。
- 结构: 通常包含一个抽象工厂类(接口)和多个具体工厂类,每个具体工厂类负责创建特定类型对象的实例。
抽象工厂 #
- 核心思想: 提供一个创建一系列相关或依赖对象的接口,但无需指定具体类。
- 特点: 更灵活,适合创建多个相关对象,例如,一个工厂创建多个类型的产品。
- 结构: 包含一个抽象工厂类(接口)、多个具体工厂类和多个抽象产品类以及多个具体产品类。每个具体工厂类负责创建一组特定类型产品对象的实例。
区别总结 #
特性 | 工厂模式 | 抽象工厂模式 |
---|---|---|
核心目的 | 创建单一类型的对象 | 创建多个相关或依赖对象的系列 |
复杂程度 | 相对简单 | 相对复杂 |
灵活性 | 较低 | 较高 |
应用场景 | 创建单一类型的对象时 | 需要创建多个相关或依赖对象的系列时 |
实例 | 创建汽车时,工厂模式可以创建一辆汽车 | 创建汽车时,抽象工厂模式可以创建一辆汽车和一个发动机 |
简单来说,工厂模式就像一个简单的工具,只负责生产一种特定类型的产品;而抽象工厂模式就像一个完整的生产线,可以生产多种相关产品的系列。
一些补充的话
- 所有的工厂都是用封装来创建对象。
- 工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
- 抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露的方法中。
- 所有工厂模式通过减少应用程序和具体类之间的依赖,而促进松耦合。
- 工厂方法允许将类的实例化延迟到子类进行。
- 抽象工厂创建相关的对象家族,而不需要依赖它的具体类。