一、概述
工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。
抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
描述:
-
显示器生产商有显示器电路板种类有非液晶的和液晶的,工厂A生成非液晶显示器电路板,工厂B生产液晶显示器电路板;
-
但发现生产显示器的其余部分也挺挣钱,决定,再建立两个工厂C和D,C负责生产非液晶显示器的其余部件,D负责生产液晶显示器的其余部件。
-
但这样耗时耗资,所以直接在工厂A中添加一条负责生产非液晶显示器的其余部件的生产线,工厂B中添加一条生产液晶显示器的其余部件的生产线。就能解决问题
二、结构
- 抽象产品:为构成系列产品的一组不同但相关的产品声明接口。
- 具体产品:是抽象产品的多种不同类型实现。所有形式都必须实现相应的抽象产品。
- 抽象工厂:接口声明了一组创建各种抽象产品的方法。
- 具体工厂:实现抽象工厂的构建方法。每个具体工厂都对应特定产品变体,且仅创建此种产品形式。
尽管具体工厂会对具体产品进行初始化,其构建方法签名必须返回相应的抽象产品。这样,使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。客户端只需通过抽象接口调用工厂和产品对象,就能与任何具体工厂/产品变体交互。
三、适用场景
-
忽略创建细节 : 客户端 不关心 产品实例 如何 被创建 , 实现等细节 ;
-
系统有多个系列产品,而系统中只消费其中某一系列产品。
-
系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
四、优缺点
优点:
- 确保同一工厂生成的产品相互匹配。
- 避免客户端和具体产品代码的耦合。
- 单一职责原则,可以将产品生成代码抽取到同一位置,使得代码易于维护。
- 开闭原则。向应用程序中引入新产品变体时,你无需修改客户端代码。
缺点:
- 引入众多接口和类,代码可能会比之前更加复杂。
- 增加了系统的抽象性和理解难度 ;
五、实例
#include<iostream>
#include<string>
#include<memory>
using namespace std;
// 抽象产品类 电影
class Movie {
public:
virtual string showMovieName() = 0;
};
// 抽象产品类 书籍
class Book {
public:
virtual string showBookName() = 0;
};
// 具体产品类 电影::国产电影
class ChineseMovie :public Movie {
string showMovieName() override {
return "《让子弹飞》";
}
};
// 具体产品类 电影::日本电影
class JapaneseMovie : public Movie {
string showMovieName() override {
return "《千与千寻》";
}
};
// 具体产品类 书籍::国产书籍
class ChineseBook : public Book {
string showBookName() override {
return "《三国演义》";
}
};
// 具体产品类 书籍::日本书籍
class JapaneseBook : public Book {
string showBookName() override {
return "《白夜行》";
}
};
// 抽象工厂类 生产电影和书籍类等
class Factory {
public:
virtual shared_ptr<Movie>productMovie() = 0;
virtual shared_ptr<Book>productBook() = 0;
};
// 具体工厂类 中国生产者
class ChineseProducer :public Factory {
public:
shared_ptr<Movie>productMovie() override {
return make_shared<ChineseMovie>();
}
shared_ptr<Book>productBook() override {
return make_shared<ChineseBook>();
}
};
// 具体工厂类 日本生产者
class JapaneseProducer :public Factory {
shared_ptr<Movie>productMovie() override {
return make_shared<JapaneseMovie>();
}
shared_ptr<Book>productBook() override {
return make_shared<JapaneseBook>();
}
};
int main()
{
shared_ptr<Factory> factory;
string conf = "China";
if (conf == "China") {
factory = make_shared<ChineseProducer>();
}
else if (conf == "Japan") {
factory = make_shared<JapaneseProducer>();
}
else {
cout << "error conf" << endl;
}
shared_ptr<Movie> movie;
shared_ptr<Book> book;
movie = factory->productMovie();
book = factory->productBook();
cout << "获取一部电影: " << movie->showMovieName() << endl;
cout << "获取一本书: " << book->showBookName() << endl;
}