Abstract Factory模式
在設計模式中,這個模式是最基礎的,而這個模式根據Eric Gamma(模式設計的提出者)的介紹的目的如下:Provide an interface for creating families of related or depandant objects without specifying their concrete classes.中文通俗的說就是:定義一個抽象基類(或者說提供一個接口),這個基類包含了很多類功能,當你需要切換場景但是所有場景都具有那些類功能的時候,你隻需要生成一個抽象基類的派生類就可以了。
而在實作上,通常要在抽象類中定義并生成所有子部件(class),這樣也可以防止由于子部件太多,總是要new XXX之後才可以使用的麻煩(特别是當子部件的名字越來越難記得時)。
Abstract Factory模式的結構
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcBTRq5UdWhVZ2ZFSiZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TNxUTMzUjMxEDMxUDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
Abstract Factory模式的應用
這個結構的應用非常廣泛,例如Eric Gamma經常舉的例子(肯定是和遊戲有關的,因為那四位博士大牛都喜歡設計遊戲),在制作一個迷宮(Maze)遊戲中,Maze就可以看作是一個Factory,而房間、牆壁、門等每個迷宮都需要的子部件就是Product了。而每一個不同的Maze就可以直接使用Factory接口就可以了。
利用上面的結構圖,可以再廣義的了解一下如何使用這個模式:
AstractProductA和AstractProductB可以了解為是兩種子部件(如迷宮中的門和房間),而ProductA1則是大門,ProductA2是小門,同理ProductB1是大房間,ProductB2是小房間,而AbstractFactoryA則是一個有大房間和大門的迷宮,是以在createProductA的時候,傳回一個ProuctA1,如此類推其他的子部件(先定義,再選擇使用)。
而在main.cpp中,隻需要調用createFactory函數就可以了。
具體實作見下一節的代碼。
Abstract Factory的實作
定義product.h
#ifndef PRODUCT_H
#define PRODUCT_H
class AbstractProductA
{
public:
virtual ~AbstractProductA();
protected: //不可以被類外通路,可以被派生類的成員函數通路
AbstractProductA(); //屏蔽構造函數
private:
};
class AbstractProductB
{
public:
virtual ~AbstractProductB();
protected: //不可以被類外通路,可以被派生類的成員函數通路
AbstractProductB(); //屏蔽構造函數
private:
};
class productA1:public AbstractProductA
{
public:
productA1();
~productA1();
protected:
private:
};
class productA2:public AbstractProductA
{
public:
productA2();
~productA2();
protected:
private:
};
class productB1:public AbstractProductB
{
public:
productB1();
~productB1();
protected:
private:
};
class productB2:public AbstractProductB
{
public:
productB2();
~productB2();
protected:
private:
};
#endif // PRODUCT_H
定義AbstractFactory.h
#ifndef ABSTRACTFACTORY_H
#define ABSTRACTFACTORY_H
#include "product.h"
class AbstractFactory
{
public:
virtual ~AbstractFactory();
virtual AbstractProductA* CreateProductA()=0; //純虛函數:隻占位置,不可以被調用,派生類需要重新定義了才可以使用
virtual AbstractProductB* CreateProductB()=0;
protected:
AbstractFactory();
private:
};
class ConcreteFactory1:public AbstractFactory
{
public:
ConcreteFactory1();
~ConcreteFactory1();
AbstractProductA* CreateProductA(); //在.cpp中實作:{ return new ProductA1();}
AbstractProductB* CreateProductB(); //在.cpp中實作:{ return new ProductB1();}
protected:
private:
};
class ConcreteFactory2:public AbstractFactory
{
public:
ConcreteFactory2();
~ConcreteFactory2();
AbstractProductA* CreateProductA(); //派生類實作
AbstractProductB* CreateProductB();
protected:
private:
};
#endif // ABSTRACTFACTORY_H
主程式使用main.cpp
#include "AbstractFactory.h"
#include "product.h"
using namespace std;
int main()
{
AbstractFactory *p1 = new ConcreteFactory1();
p->CreateProductA();
p->CreateProductB();
AbstractFactory *p2 = new ConcreteFactory2();
p->CreateProductA();
p->CreateProductB();
return 0;
}