【声明】本编码题目来源于【题目页面 (kamacoder.com)】
【提示:如果不想看文字介绍,可以直接跳转到C++编码部分】
【简介】什么是抽象工厂模式
抽象⼯⼚模式也是⼀种创建型设计模式,提供了⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
在⼯⼚⽅法模式中,每个具体⼯⼚只负责创建单⼀的产品。但是如果有多类产品呢,⽐如说“⼿机”,⼀个品牌的⼿机有⾼端机、中低端机之分,这些具体的产品都需要建⽴⼀个单独的⼯⼚类,但是它们都是相互关联的,都共同属于同⼀个品牌,这就可以使⽤到【抽象⼯⼚模式】。
抽象⼯⼚模式可以确保⼀系列相关的产品被⼀起创建,这些产品能够相互配合使⽤,再举个例⼦,有⼀些家具,⽐如沙发、茶⼏、椅⼦,都具有古典⻛格的和现代⻛格的,抽象⼯⼚模式可以将⽣产现代⻛格的家具放在⼀个⼯⼚类中,将⽣产古典⻛格的家具放在另⼀个⼯⼚类中,这样每个⼯⼚类就可以⽣产⼀系列的家具。
【基本结构】
抽象⼯⼚模式包含多个抽象产品接⼝,多个具体产品类,⼀个抽象⼯⼚接⼝和多个具体⼯⼚,每个具体⼯⼚负责创建⼀组相关的产品。
- 抽象产品接⼝AbstractProduct : 定义产品的接⼝,可以定义多个抽象产品接⼝,⽐如说沙发、椅⼦、茶⼏都是抽象产品。
- 具体产品类ConcreteProduct : 实现抽象产品接⼝,产品的具体实现,古典⻛格和沙发和现代⻛格的沙发都是具体产品。
- 抽象⼯⼚接⼝AbstractFactory : 声明⼀组⽤于创建产品的⽅法,每个⽅法对应⼀个产品。
- 具体⼯⼚类ConcreteFactory : 实现抽象⼯⼚接⼝,负责创建⼀组具体产品的对象,在本例中,⽣产古典⻛格的⼯⼚和⽣产现代⻛格的⼯⼚都是具体实例。
在上⾯的图示中:
AbstractProductA/B/C 就是抽象产品,
ConcreteProductA2/A2/B1/B2/C1/C2 就是抽象产品的实现,
AbstractFactory 定义了抽象⼯⼚接⼝,接⼝⾥的⽅法⽤于创建具体的产品,ConcreteFactory就是具体⼯⼚类,可以创建⼀组相关的产品。
【实现步骤】
- 定义抽象产品接⼝(可以有多个),接⼝中声明产品的公共⽅法。
- 实现具体产品类,在类中实现抽象产品接⼝中的⽅法。
- 定义抽象⼯⼚接⼝,声明⼀组⽤于创建产品的⽅法。
- 实现具体⼯⼚类,分别实现抽象⼯⼚接⼝中的⽅法,每个⽅法负责创建⼀组相关的产品。
- 在客户端中使⽤抽象⼯⼚和抽象产品,⽽不直接使⽤具体产品的类名。
【C++编码实例】
1.题目描述
小明家新开了两个工厂用来生产家具,一个生产现代风格的沙发和椅子,一个生产古典风格的沙发和椅子,现在工厂收到了一笔订单,请你帮他设计一个系统,描述订单需要生产家具的信息。
2.输入描述
输入的第一行是一个整数 N(1 ≤ N ≤ 100),表示订单的数量。 接下来的 N 行,每行输入一个字符串,字符串表示家具的类型。家具类型分为 "modern" 和 "classical" 两种。
3.输出描述
对于每笔订单,输出字符串表示该订单需要生产家具的信息。
modern订单会输出下面两行字符串 :
modern chair
modern sofa
classical订单会输出下面两行字符串 :
classical chair
classical soft
4.编码实现
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// 前置声明
class Sofa;
class Chair;
class Classic;
class ModernSofa;
class ModernChair;
class ClassicSofa;
class ClassicChair;
// 定义抽象产品
// 现代风格类
class Sofa{
public:
// 声明虚函数时一定要加上空实现 或者声明为纯虚函数
virtual void PrintSofa() = 0;
};
// 古典风格类
class Chair{
public:
// 声明虚函数时一定要加上空实现 或者声明为纯虚函数
virtual void PrintChair() = 0;
};
// 实现具体产品类
// 现代风格的沙发
class ModernSofa : public Sofa
{
public:
void PrintSofa() override
{
std::cout << "modern sofa" << endl;
}
};
// 现代风格的椅子
class ModernChair : public Chair
{
public:
void PrintChair() override
{
std::cout << "modern chair" << endl;
}
};
// 古典风格的沙发
class ClassicSofa : public Sofa
{
public:
void PrintSofa() override
{
std::cout << "classical sofa" << endl;
}
};
// 古典风格的椅子
class ClassicChair : public Chair
{
public:
void PrintChair() override
{
std::cout << "classical chair" << endl;
}
};
// 定义抽象工厂接口 -- 实例化 抽象的产品(风格)
class ProductFactory{
public:
// 后续需要重写
// 声明虚函数时一定要加上空实现 或者声明为纯虚函数
virtual Sofa* CreateSofa() = 0;
virtual Chair* CreateChair() = 0;
};
// 实现具体工厂类(以产品的特性分类 而不是具体的产品)
// 现代工厂
class ModernProductFactory : public ProductFactory
{
public:
// 生产现代风的沙发
Sofa* CreateSofa() override
{
return (new ModernSofa());
}
// 生产现代风的椅子
Chair* CreateChair() override
{
return (new ModernChair());
}
};
// 古典工厂
class ClassicProductFactory : public ProductFactory
{
public:
// 生产古典风的沙发
Sofa* CreateSofa() override
{
return (new ClassicSofa());
}
// 生产古典风的椅子
Chair* CreateChair() override
{
return (new ClassicChair());
}
};
// 工厂产品 管理类
int main()
{
// 产品工厂的抽象基类 用于后续不同派生类的创建
ProductFactory *factoryPointer = nullptr;
// 订单数量
int orderNum = 0;
// 输入的家具类型
string furnitureType = "";
// 已有家具类型
string modern = "modern";
string classical = "classical";
// 输入订单数量
std::cin >> orderNum;
for(int i = 0; i < orderNum; i++)
{
std::cin >> furnitureType;
if(furnitureType == modern)
{
// 创建 现代 工厂
factoryPointer = new ModernProductFactory();
// 创建具体化的 椅子和沙发 对象 同时使用dynamic_cast完成向下类型转换
ModernSofa *sofa = dynamic_cast<ModernSofa *>(factoryPointer->CreateSofa());
ModernChair *chair = dynamic_cast<ModernChair *>(factoryPointer->CreateChair());
// 执行相应操作
chair->PrintChair();
sofa->PrintSofa();
// 用完记得析构掉
delete chair;
chair = nullptr;
delete sofa;
sofa = nullptr;
}
else if(furnitureType == classical)
{
// 创建古典工厂
factoryPointer = new ClassicProductFactory();
// 创建具体化的 椅子和沙发 对象
ClassicSofa *sofa = dynamic_cast<ClassicSofa *>(factoryPointer->CreateSofa());
ClassicChair *chair = dynamic_cast<ClassicChair *>(factoryPointer->CreateChair());
// 执行相应操作
chair->PrintChair();
sofa->PrintSofa();
// 用完记得析构掉
delete chair;
chair = nullptr;
delete sofa;
sofa = nullptr;
}
else continue;
// 用完记得析构掉
delete factoryPointer;
factoryPointer = nullptr;
}
return 0;
}
......
To be continued.
【补充】简单⼯⼚、⼯⼚⽅法、抽象⼯⼚的区别
- 简单⼯⼚模式:⼀个⼯⼚⽅法创建所有具体产品
- ⼯⼚⽅法模式:⼀个⼯⼚⽅法创建⼀个具体产品
- 抽象⼯⼚模式:⼀个⼯⼚⽅法可以创建⼀类具体产品