1. 什么是抽象工厂模式
抽象工厂模式也是一种创建型设计模式,提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
这样的描述似乎理解起来很困难,我们可以把它与【工厂方法模式】联系起来看。
之前我们已经介绍了“工厂方法模式”,那为什么还有要抽象工厂模式呢?
这就涉及到创建“多类”对象了,在工厂方法模式中,每个具体工厂只负责创建单一的产品。但是如果有多类产品呢,比如说“手机”,一个品牌的手机有高端机、中低端机之分,这些具体的产品都需要建立一个单独的工厂类,但是它们都是相互关联的,都共同属于同一个品牌,这就可以使用到【抽象工厂模式】。
抽象工厂模式可以确保一系列相关的产品被一起创建,这些产品能够相互配合使用,再举个例子,有一些家具,比如沙发、茶几、椅子,都具有古典风格的和现代风格的,抽象工厂模式可以将生产现代风格的家具放在一个工厂类中,将生产古典风格的家具放在另一个工厂类中,这样每个工厂类就可以生产一系列的家具。
2. 基本结构
抽象工厂模式包含多个抽象产品接口,多个具体产品类,一个抽象工厂接口和多个具体工厂,每个具体工厂负责创建一组相关的产品。
- 抽象产品接口
AbstractProduct
: 定义产品的接口,可以定义多个抽象产品接口,比如说沙发、椅子、茶几都是抽象产品。
- 具体产品类
ConcreteProduct
: 实现抽象产品接口,产品的具体实现,古典风格和沙发和现代风格的沙发都是具体产品。
- 抽象工厂接口
AbstractFactory
: 声明一组用于创建产品的方法,每个方法对应一个产品。
- 具体工厂类
ConcreteFactory
: 实现抽象工厂接口,负责创建一组具体产品的对象,在本例中,生产古典风格的工厂和生产现代风格的工厂都是具体实例。
在上面的图示中:AbstractProductA/B/C
就是抽象产品,ConcreteProductA1/A2/B1/B2/C1/C2
就是抽象产品的实现,AbstractFactory
定义了抽象工厂接口,接口里的方法用于创建具体的产品,而ConcreteFactory
就是具体工厂类,可以创建一组相关的产品。
3. 基本实现
想要实现抽象工厂模式,需要遵循以下步骤:
- 定义抽象产品接口(可以有多个),接口中声明产品的公共方法。
- 实现具体产品类,在类中实现抽象产品接口中的方法。
- 定义抽象工厂接口,声明一组用于创建产品的方法。
- 实现具体工厂类,分别实现抽象工厂接口中的方法,每个方法负责创建一组相关的产品。
- 在客户端中使用抽象工厂和抽象产品,而不直接使用具体产品的类名。
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
interface ProductA { void display(); }
interface ProductB { void show(); }
class ConcreteProductA1 implements ProductA { @Override public void display() { System.out.println("Concrete Product A1"); } }
class ConcreteProductA2 implements ProductA { @Override public void display() { System.out.println("Concrete Product A2"); } }
class ConcreteProductB1 implements ProductB { @Override public void show() { System.out.println("Concrete Product B1"); } }
class ConcreteProductB2 implements ProductB { @Override public void show() { System.out.println("Concrete Product B2"); } }
interface AbstractFactory { ProductA createProductA(); ProductB createProductB(); }
class ConcreteFactory1 implements AbstractFactory { @Override public ProductA createProductA() { return new ConcreteProductA1(); }
@Override public ProductB createProductB() { return new ConcreteProductB1(); } }
class ConcreteFactory2 implements AbstractFactory { @Override public ProductA createProductA() { return new ConcreteProductA2(); }
@Override public ProductB createProductB() { return new ConcreteProductB2(); } }
public class AbstractFactoryExample { public static void main(String[] args) { AbstractFactory factory1 = new ConcreteFactory1(); ProductA productA1 = factory1.createProductA(); ProductB productB1 = factory1.createProductB(); productA1.display(); productB1.show();
AbstractFactory factory2 = new ConcreteFactory2(); ProductA productA2 = factory2.createProductA(); ProductB productB2 = factory2.createProductB(); productA2.display(); productB2.show(); } }
|
4. 应用场景
抽象工厂模式能够保证一系列相关的产品一起使用,并且在不修改客户端代码的情况下,可以方便地替换整个产品系列。但是当需要增加新的产品类时,除了要增加新的具体产品类,还需要修改抽象工厂接口及其所有的具体工厂类,扩展性相对较差。因此抽象工厂模式特别适用于一系列相关或相互依赖的产品被一起创建的情况,典型的应用场景是使用抽象工厂模式来创建与不同数据库的连接对象。
简单工厂、工厂方法、抽象工厂的区别
- 简单工厂模式:一个工厂方法创建所有具体产品
- 工厂方法模式:一个工厂方法创建一个具体产品
- 抽象工厂模式:一个工厂方法可以创建一类具体产品
5. 本题代码
5.1 抽象工厂模式-家具工厂
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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| import java.util.Scanner;
interface Chair { void showInfo(); }
class ModernChair implements Chair { @Override public void showInfo() { System.out.println("modern chair"); } }
class ClassicalChair implements Chair { @Override public void showInfo() { System.out.println("classical chair"); } }
interface Sofa { void displayInfo(); }
class ModernSofa implements Sofa { @Override public void displayInfo() { System.out.println("modern sofa"); } }
class ClassicalSofa implements Sofa { @Override public void displayInfo() { System.out.println("classical sofa"); } }
interface FurnitureFactory { Chair createChair(); Sofa createSofa(); }
class ModernFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new ModernChair(); }
@Override public Sofa createSofa() { return new ModernSofa(); } }
class ClassicalFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new ClassicalChair(); }
@Override public Sofa createSofa() { return new ClassicalSofa(); } }
public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
for (int i = 0; i < N; i++) { String furnitureType = scanner.next();
FurnitureFactory factory = null; if (furnitureType.equals("modern")) { factory = new ModernFurnitureFactory(); } else if (furnitureType.equals("classical")) { factory = new ClassicalFurnitureFactory(); }
Chair chair = factory.createChair(); Sofa sofa = factory.createSofa();
chair.showInfo(); sofa.displayInfo(); } } }
|