前言
尊重原创,本系列文本解析部分主要基于Candidate for Master’s Degree School of Computer Wuhan University的K_Eckel([email protected])《设计模式精解-GoF 23 种设计模式解析附 C++实现源码》。为了避免重造轮子,本系列博文对源码在ubuntu16.04下做了验证并上传到了gitee,再次感谢。
如有问题,可邮件联系我([email protected])并共同探讨解决方案。
目录
创建型模式(Creating Pattern)
Factory 模式 | AbstactFactory 模式 | Singleton 模式 | Builder 模式 | Prototype 模式
结构型模式(Structrual Pattern)
Bridge 模式 | Adapter 模式 | Decorator 模式 | Composite 模式 | Flyweight 模式 | Facade 模式 | Proxy 模式
行为型模式(Behavioral Pattern)
Template 模式 | Strategy 模式 | State 模式 | Observer 模式 | Memento 模式 | Mediator 模式 | Command 模式 | Visitor 模式 | Iterator 模式 | Interpreter 模式 | Chain of Responsibility 模式
AbstactFactory模式简介:
在设计模式中,这个模式是最基础的,而这个模式根据Eric Gamma(模式设计的提出者)的介绍的目的如下:Provide an interface for creating families of related or depandant objects without specifying their concrete classes.中文通俗的说就是:定义一个抽象基类(或者说提供一个接口),这个基类包含了很多类功能,当你需要切换场景但是所有场景都具有那些类功能的时候,你只需要生成一个抽象基类的派生类就可以了。
而在实现上,通常要在抽象类中定义并生成所有子部件(class),这样也可以防止由于子部件太多,总是要new XXX
之后才可以使用的麻烦(特别是当子部件的名字越来越难记得时)。
问题
假设我们要开发一款游戏,当然为了吸引更多的人玩,游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理)。于是我们就可以采用这样一种处理策略:为游戏设立等级,初级、中级、高级甚至有BT 级。假设也是过关的游戏,每个关卡都有一些怪物(monster)守着,玩家要把这些怪物干掉才可以过关。作为开发者,我们就不得不创建怪物的类,然后初级怪物、中级怪物等都继承自怪物类(当然不同种类的则需要另创建类,但是模式相同)。在每个关卡,我们都要创建怪物的实例,例如初级就创建初级怪物(有很多种类)、中级创建中级怪物等。可以想
象在这个系统中,将会有成千上万的怪物实例要创建,问题是还要保证创建的时候不会出错:初级不能创建 BT 级的怪物(玩家就郁闷了,玩家一郁闷,游戏也就挂挂了),反之也不可以。
AbstractFactory 模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。
模式选择
AbstractFactory 模式典型的结构图为:
图 1:AbstractFactory Pattern 结构图
AbstractFactory 模式关键就是将这一组对象的创建封装到一个用于创建对象的类ConcreteFactory
中,维护这样一个创建类总比维护 n 多相关对象的创建过程要简单的多。
实现
完整代码示例(code)
AbstractFactory 模式的实现比较简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 Visual Studio Code,Version: 1.36.1 下测试运行)。
源码gitee地址:点击这里
代码目录结构:
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/AbstractFactory/src$ tree ../../
├── include
│ ├── AbstractFactory.h
│ └── Product.h
└── src
├── AbstractFactory.cpp
├── a.out
├── main.cpp
└── Product.cpp
2 directories, 6 files
AbstractFactory.h:
// AbstractFactory.h
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
class AbstractProductA;
class AbstractProductB;
class AbstractFactory {
private:
/* data */
protected:
AbstractFactory(/* args */);
public:
virtual ~AbstractFactory();
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
};
class ConcreteFactory1 : public AbstractFactory {
private:
protected:
public:
ConcreteFactory1();
~ConcreteFactory1();
AbstractProductA* CreateProductA();
AbstractProductB* CreateProductB();
};
class ConcreteFactory2 : public AbstractFactory {
private:
protected:
public:
ConcreteFactory2();
~ConcreteFactory2();
AbstractProductA* CreateProductA();
AbstractProductB* CreateProductB();
};
#endif // ~_ABSTRACTFACTORY_H_
Product.h:
// Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class AbstractProductA {
private:
/* data */
protected:
AbstractProductA(/* args */);
public:
virtual ~AbstractProductA();
};
class AbstractProductB {
private:
/* data */
protected:
AbstractProductB(/* args */);
public:
virtual ~AbstractProductB();
};
class ProductA1: public AbstractProductA
{
private:
/* data */
public:
ProductA1(/* args */);
~ProductA1();
};
class ProductA2: public AbstractProductA
{
private:
/* data */
public:
ProductA2(/* args */);
~ProductA2();
};
class ProductB1: public AbstractProductB
{
private:
/* data */
public:
ProductB1(/* args */);
~ProductB1();
};
class ProductB2: public AbstractProductB
{
private:
/* data */
public:
ProductB2(/* args */);
~ProductB2();
};
#endif //~PRODUCT_H_ECT_H_
AbstractFactory.cpp:
//AbstractFactory.cpp
#include "../include/AbstractFactory.h"
#include "../include/Product.h"
#include<iostream>
using namespace std;
AbstractFactory::AbstractFactory(){}
AbstractFactory::~AbstractFactory(){}
ConcreteFactory1::ConcreteFactory1(){}
ConcreteFactory1::~ConcreteFactory1(){}
AbstractProductA* ConcreteFactory1::CreateProductA(){
return new ProductA1();
}
AbstractProductB* ConcreteFactory1::CreateProductB(){
return new ProductB1();
}
ConcreteFactory2::ConcreteFactory2(){}
ConcreteFactory2::~ConcreteFactory2(){}
AbstractProductA* ConcreteFactory2::CreateProductA(){
return new ProductA2();
}
AbstractProductB* ConcreteFactory2::CreateProductB(){
return new ProductB2();
}
Product.cpp:
// Product.cpp
#include "../include/Product.h"
#include <iostream>
using namespace std;
AbstractProductA::AbstractProductA() {}
AbstractProductA::~AbstractProductA() {}
AbstractProductB::AbstractProductB() {}
AbstractProductB::~AbstractProductB() {}
ProductA1::ProductA1() { printf("ProductA1... \n"); }
ProductA1::~ProductA1() {}
ProductA2::ProductA2() { printf("ProductA2... \n"); }
ProductA2::~ProductA2() {}
ProductB1::ProductB1() { printf("ProductB1... \n"); }
ProductB1::~ProductB1() {}
ProductB2::ProductB2() { printf("ProductB2... \n"); }
ProductB2::~ProductB2() {}
main.cpp:
// main.cpp
#include <iostream>
#include "../include/AbstractFactory.h"
using namespace std;
int main(int argc, char* argv[]) {
AbstractFactory* cf1 = new ConcreteFactory1();
cf1->CreateProductA();
cf1->CreateProductB();
AbstractFactory* cf2 = new ConcreteFactory2();
cf2->CreateProductA();
cf2->CreateProductB();
return 0;
}
代码说明
AbstractFactory 模式的实现代码很简单,在测试程序中可以看到,当我们要创建一组对象(ProductA1
,ProductA2
)的时候我们只用维护一个创建对象(ConcreteFactory1
),大大简化了维护的成本和工作。
编译运行结果:
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/AbstractFactory/src$ g++ *.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/AbstractFactory/src$ ./a.out ProductA1...
ProductB1...
ProductA2...
ProductB2...
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/AbstractFactory/src$ ^C
patten@patten-hp:~/workspace/others/cpp/designPatterns/creatingPattern/AbstractFactory/src$
讨论
AbstractFactory 模式和 Factory 模式的区别是初学(使用)设计模式时候的一个容易引起困惑的地方。实际上,AbstractFactory 模式是为创建一组(有多类)相关或依赖的对象提供创建接口,而Factory 模式正如我在相应的文档中分析的是为一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory 模式通常都是使用 Factory 模式实ConcreteFactory1
。