一个具体的工厂,可以专门生产单一某一种东西,比如说只生产手机。但是一个品牌的手机有高端机、中端机之分,这些具体的属于某一档次的产品都需要单独建立一个工厂类,但是它们之间又彼此关联,因为都共同属于一个品牌。我们说这种叫做“多类”对象。
除了手机之外,还有比如沙发、茶几、椅子,不同于手机的高端型号和低端型号,取而代之的可以是不同的样式风格,比如古典风格的和现代风格的。每一种风格的产品都需要单独建立一个工厂类,但是他们本质上都属于同一样东西。我们可以从这个角度理解“多类对象”,即,就是同一对象的多种类别。
图中包含以下元素:
- 抽象产品接口:AbstractProduct
- 具体产品类:ConcreteProduct
- 抽象工厂接口:AbstractFactory
- 具体工厂类:ConcreateFactory
Java代码:
// 1. 定义抽象产品
// 抽象产品A
interface ProductA {
void display();
}
// 抽象产品B
interface ProductB {
void show();
}
// 2. 实现具体产品类
// 具体产品A1
class ConcreteProductA1 implements ProductA {
@Override
public void display() {
System.out.println("Concrete Product A1");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
@Override
public void display() {
System.out.println("Concrete Product A2");
}
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
@Override
public void show() {
System.out.println("Concrete Product B1");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
@Override
public void show() {
System.out.println("Concrete Product B2");
}
}
// 3. 定义抽象工厂接口
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 4. 实现具体工厂类
// 具体工厂1,生产产品A1和B1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2,生产产品A2和B2
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) {
// 使用工厂1创建产品A1和产品B1
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.display();
productB1.show();
// 使用工厂2创建产品A2和产品B2
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.display();
productB2.show();
}
}
为了避免跟之前的工厂方法模式混淆,这里做一个区别:
- 简单工厂模式:一个工厂方法创建所有具体产品
- 工厂方法模式:一个工厂方法创建一个具体产品
- 抽象工厂模式:一个工厂方法创建一个具体产品的某一类
典型的应用场景是,使用抽象工厂模式来创建与不同数据库的连接对象。
总结一下就是抽象工厂模式特别适用于一系列相关或相互依赖的产品被一起创建的情况。
当需要增加新产品时(是新产品而不是某一产品的新型号),则需要增加新的具体产品类,然后修改抽象工厂接口以及所有的具体工厂类,扩展性相对较差。
【设计模式专题之抽象工厂模式】3. 家具工厂
CPP版代码:
#include <iostream>
#include <string>
// 抽象椅子接口
class Chair {
public:
virtual void showInfo() = 0;
};
// 具体现代风格椅子
class ModernChair : public Chair {
public:
void showInfo() override {
std::cout << "modern chair" << std::endl;
}
};
// 具体古典风格椅子
class ClassicalChair : public Chair {
public:
void showInfo() override {
std::cout << "classical chair" << std::endl;
}
};
// 抽象沙发接口
class Sofa {
public:
virtual void displayInfo() = 0;
};
// 具体现代风格沙发
class ModernSofa : public Sofa {
public:
void displayInfo() override {
std::cout << "modern sofa" << std::endl;
}
};
// 具体古典风格沙发
class ClassicalSofa : public Sofa {
public:
void displayInfo() override {
std::cout << "classical sofa" << std::endl;
}
};
// 抽象家居工厂接口
class FurnitureFactory {
public:
virtual Chair* createChair() = 0;
virtual Sofa* createSofa() = 0;
};
// 具体现代风格家居工厂
class ModernFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new ModernChair();
}
Sofa* createSofa() override {
return new ModernSofa();
}
};
// 具体古典风格家居工厂
class ClassicalFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new ClassicalChair();
}
Sofa* createSofa() override {
return new ClassicalSofa();
}
};
int main() {
// 读取订单数量
int N;
std::cin >> N;
// 处理每个订单
for (int i = 0; i < N; i++) {
// 读取家具类型
std::string furnitureType;
std::cin >> furnitureType;
// 创建相应风格的家居装饰品工厂
FurnitureFactory* factory = nullptr;
if (furnitureType == "modern") {
factory = new ModernFurnitureFactory();
} else if (furnitureType == "classical") {
factory = new ClassicalFurnitureFactory();
}
// 根据工厂生产椅子和沙发
Chair* chair = factory->createChair();
Sofa* sofa = factory->createSofa();
// 输出家具信息
chair->showInfo();
sofa->displayInfo();
// 释放动态分配的对象
delete chair;
delete sofa;
delete factory;
}
return 0;
}