博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
抽象工厂模式
阅读量:3941 次
发布时间:2019-05-24

本文共 2933 字,大约阅读时间需要 9 分钟。

抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

适用场景:

  • 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节
  • 强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量的重复代码
  • 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现

抽象工厂模式的结构图

在这里插入图片描述

对应上面的的抽象工厂模式的结构图

我们对下面的对象进行抽象
假设这里有两种车,奔驰 宝马
有两个国家的品牌,中国,美国
中国生产的叫 中国奔驰,中国宝马
美国生产的叫 美国奔驰,美国宝马
在这里插入图片描述
抽象工厂模式的好处:

  • 易于交换产品系列,由于具体的产品类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
  • 它让具体的创建实例过程与客户端分离,客户端通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端的代码中。

缺点:

  • 规定了所有可能被创建的产品集合,产品簇中扩展新的产品困难;
  • 增加了系统的抽象性和理解难度

下面是代码的实现

#include 
#include
using namespace std;//对工厂进行抽象class BMW{
public: BMW(string str):name(str){
} virtual void run() = 0; protected: string name;};class BENZ{
public: BENZ(string str):name(str){
} virtual void run() = 0; protected: string name;};class ChinaBMW:public BMW{
public: ChinaBMW(string str):BMW(str){
} void run() {
cout << name << "宝马车在路上" << endl;}};class ChinaBENZ:public BENZ{
public: ChinaBENZ(string str):BENZ(str){
} void run() {
cout << name << " 奔驰车在路上 " << endl;}};class AmericaBMW:public BMW{
public: AmericaBMW(string str):BMW(str){
} void run() {
cout << name << "宝马车在路上" << endl; }};class AmericaBENZ:public BENZ{
public: AmericaBENZ(string str):BENZ(str){
} void run() {
cout << name << " 奔驰车在路上 " << endl;}};//抽象工厂类class CarFactory{
public: virtual BMW *createBMWCar() = 0; virtual BENZ *createBENZCar() = 0;};class AmericaFactort:public CarFactory{
public: BMW *createBMWCar() {
return new AmericaBMW("美国"); } BENZ *createBENZCar() {
return new AmericaBENZ("美国"); }};class ChinaFactory:public CarFactory{
public: BMW *createBMWCar() {
return new AmericaBMW("中国"); } BENZ *createBENZCar() {
return new AmericaBENZ("中国"); }};int main(){
CarFactory *china = new ChinaFactory(); CarFactory *america = new AmericaFactort(); BMW *CBMW = china->createBMWCar(); BENZ *CBNEA = china->createBENZCar(); BMW *ABMW = america->createBMWCar(); BENZ *ABENZ = america->createBENZCar(); CBMW->run(); CBNEA->run(); ABMW->run(); ABENZ->run(); return 0;}

在上面的模式中,如果想要添加一种产品,就要修改CarFactory,AmericaFactort,ChinaFactory,代码需要大批量的修改,下面用简单工厂模式改进抽象工厂模式,去掉

CarFactory,AmericaFactort,ChinaFactory这三个工厂类,用一个Car 来代替

class Car{
public: void setCountry(char ch) {
c = ch; } BMW *createBMWCar() {
switch (c) {
case 'c': return new ChinaBMW("中国"); case 'a': return new AmericaBMW("美国"); default: break; } } BENZ *createBENZCar() {
switch (c) {
case 'c': return new ChinaBENZ("中国"); case 'a': return new AmericaBENZ("美国"); default: break; } }private: char c; //设置哪个国家标志};int main(){
Car car; car.setCountry('c'); BENZ* cbenz = car.createBENZCar(); BMW * cbmw = car.createBMWCar(); cbenz->run(); cbmw->run(); car.setCountry('a'); BENZ *abenz = car.createBENZCar(); BMW *abmw = car.createBMWCar(); abenz->run(); abmw->run(); return 0;}

在改进后的模式中,如果要添加一种车,只要在Car 类中添加一个函数即可,但是如果要添加一个厂商,比如英国,则需要在所有的函数中添加case分支。

转载地址:http://mxnwi.baihongyu.com/

你可能感兴趣的文章
深度学习中的注意力机制(2017版)-易理解
查看>>
Transformer解析-易理解
查看>>
多维数组[:,0]和[:0:1]获取的区别
查看>>
复原Ip地址
查看>>
重建二叉树
查看>>
二叉树根节点到叶子节点的路径数字之和
查看>>
根节点到叶子节点的节点值之和等于 sum的路径
查看>>
判断二叉树是否有从根节点到叶子节点的节点值之和等于sum的路径
查看>>
反转字符串
查看>>
环形链表
查看>>
删除链表的倒数第N个节点
查看>>
回文链表
查看>>
容器盛水问题
查看>>
滑动窗口最大值
查看>>
win7 文件删除后要刷新后才会消失
查看>>
用ffmpeg转多音轨的mkv文件
查看>>
ubuntu12.04 安装VLC,在root用户下不能使用的问题
查看>>
简单而又完整的Makefile
查看>>
GNU/Linux下如何卸载源码安装的软件
查看>>
ffmpeg 常用 命令随手记
查看>>