目录
何时选用抽象工厂:强调一系列相关产品接口、联合使用它们的时候
首先来看不使用设计模式的做法:
- #include
- using namespace std;
-
- class FrameApi {
- public:
- virtual void draw() = 0;
- protected:
- FrameApi() {}
- };
-
- class LayoutApi {
- public:
- virtual void installFrame() = 0;
- protected:
- LayoutApi() {}
- };
-
- //PC Frame
- class ComputerFrame :public FrameApi {
- public:
- ComputerFrame(int pins) :m_pins(pins) {}
- void draw() {
- cout << "现在是PC Frame,分辨率适用:" << m_pins << endl;
- }
- private:
- int m_pins;
- };
- //Mobile Frame
- class MobileFrame :public FrameApi {
- public:
- MobileFrame(int pins) :m_pins() {}
- void draw() {
- cout << "现在是Mobile Frame,分辨率适用:" << m_pins << endl;
- }
- private:
- int m_pins;
- };
-
- //高分辨率布局
- class HighLayout :public LayoutApi {
- public:
- HighLayout(int FrameAdapterPins) :m_FrameAdapterPins(FrameAdapterPins) {}
- void installFrame() {
- cout << "现在是在PC环境下使用高分辨率布局" << m_FrameAdapterPins << endl;
- }
- private:
- int m_FrameAdapterPins;
- };
-
- //低分辨率布局
- class LowLayout :public LayoutApi {
- public:
- LowLayout(int FrameAdapterPins) :m_FrameAdapterPins(FrameAdapterPins) {}
- void installFrame() {
- cout << "现在是在Mobile环境下使用低分辨率布局" << m_FrameAdapterPins << endl;
- }
- private:
- int m_FrameAdapterPins;
- };
-
- //创建产品的简单工厂
- class FrameFactory {
- public:
- static FrameApi* createFrame(int type) {
- if (type == 1)return new ComputerFrame(1024);
- if (type == 2)return new MobileFrame(800);
- return nullptr;
- }
- };
-
- class LayoutFactory {
- public:
- static LayoutApi* createLayout(int type) {
- if (type == 1)return new HighLayout(1024);
- if (type == 2)return new LowLayout(800);
- return nullptr;
- }
- };
-
- class GUIEngineer {
- public:
- void prepareDraw(int FrameType, int LayoutType) {
- this->pFrame = FrameFactory::createFrame(FrameType);
- this->pLayout = LayoutFactory::createLayout(LayoutType);
- pFrame->draw();
- pLayout->installFrame();
- }
- private:
- FrameApi* pFrame;
- LayoutApi* pLayout;
- };
-
- int main() {
- GUIEngineer* pEng = new GUIEngineer;
- pEng->prepareDraw(1, 1);
- return 0;
- }

这样的作法,应该告诉客户:
FrameType是用来选择Frame控件的类型
LayoutType是用来选择布局管理器的类型
如果客户这么做:
pEng->prepareDraw(1, 2);
则:

明显结果不适配。
为了避免这种结果,我们需要进行类似提取公因式的办法,来解决此类问题,把相像的关系进行提取,避免造成关系不适配的情况。
这里就引出抽象工厂的概念:
我们将简单工厂替换为抽象工厂,也就是将产品替换为产品簇:
- #include
- using namespace std;
-
- class FrameApi {
- public:
- virtual void draw() = 0;
- protected:
- FrameApi() {}
- };
-
- class LayoutApi {
- public:
- virtual void installFrame() = 0;
- protected:
- LayoutApi() {}
- };
-
- //PC Frame
- class ComputerFrame :public FrameApi {
- public:
- ComputerFrame(int pins) :m_pins(pins) {}
- void draw() {
- cout << "现在是PC Frame,分辨率适用:" << m_pins << endl;
- }
- private:
- int m_pins;
- };
- //Mobile Frame
- class MobileFrame :public FrameApi {
- public:
- MobileFrame(int pins) :m_pins() {}
- void draw() {
- cout << "现在是Mobile Frame,分辨率适用:" << m_pins << endl;
- }
- private:
- int m_pins;
- };
-
- //高分辨率布局
- class HighLayout :public LayoutApi {
- public:
- HighLayout(int FrameAdapterPins) :m_FrameAdapterPins(FrameAdapterPins) {}
- void installFrame() {
- cout << "现在是在PC环境下使用高分辨率布局" << m_FrameAdapterPins << endl;
- }
- private:
- int m_FrameAdapterPins;
- };
-
- //低分辨率布局
- class LowLayout :public LayoutApi {
- public:
- LowLayout(int FrameAdapterPins) :m_FrameAdapterPins(FrameAdapterPins) {}
- void installFrame() {
- cout << "现在是在Mobile环境下使用低分辨率布局" << m_FrameAdapterPins << endl;
- }
- private:
- int m_FrameAdapterPins;
- };
-
-
-
-
- //AbstractFactory产品簇
- class AbstractFactory {
- public:
- virtual FrameApi* createFrameApi() = 0;
- virtual LayoutApi* createLayoutApi() = 0;
- protected:
- AbstractFactory(){}
- };
- //产品簇1
- class Schemal :public AbstractFactory {
- public:
- FrameApi* createFrameApi() {
- return new ComputerFrame(1024);
- }
- LayoutApi* createLayoutApi() {
- return new HighLayout(1024);
- }
- };
- //产品簇2
- class Schema2 :public AbstractFactory {
- public:
- FrameApi* createFrameApi() {
- return new MobileFrame(1024);
- }
- LayoutApi* createLayoutApi() {
- return new LowLayout(1024);
- }
- };
-
- class AdanvancedGuiEngineer {
- public:
- void prepareMaterials(AbstractFactory* pSchema) {
- this->pFrame = pSchema->createFrameApi();
- this->pLayout = pSchema->createLayoutApi();
- pFrame->draw();
- pLayout->installFrame();
- }
- private:
- FrameApi* pFrame;
- LayoutApi* pLayout;
- };
-
- int main() {
- AdanvancedGuiEngineer* pEng = new AdanvancedGuiEngineer();
- pEng->prepareMaterials(new Schemal());
- return 0;
- }

Nice!
其实就相当于:点套餐,这样就不会出现不适配的情况。

