• c++设计模式系列----factory模式


    问题:

        假设我们要开发一个游戏--打怪物,首先,游戏有分等级,假设有初级,中级两个个等级(就不用flappy bird模式了,那个比较特殊,对一个玩家来说是难以具有持久吸引力的!),不同的等级怪物也是不一样的,我们不妨假设初级为怪物A1, B1,中级为怪物A2,B2。如图所示:

                                                                          

    设计:

    那么根据面向对象思想,我们来考虑一下应该怎么设计程序结构,首先不同等级的怪物要由不同的对象来产生,即相当于不同等级的怪物也应该由不同类型的工厂来生产。但不同等级的怪物都是怪物,它们具有某些共同点,应该继承自同一个父怪物类。同样,不同等级的工厂也应该继承自同一个父工厂类。我们称这样的父工厂类和父怪物类为AbstractFactory和AbstractProduct。这个模式成为AbstractFactory模式。

    AbstractFactory模式的典型结构图为:

                                   

    其实这里我们还应该考虑的一个问题是我们为什么要增加一个AbstractFactory类,在factory模式中,是不需要AbstractFactory而是直接由factory类来生产product的,即如下的结构:

                                     

    但我们从第二个图可以很容易看出,这里的factory只有一个,只能生产同一个等级的怪物。

    首先,我们用factory的是为了解决两个问题:

    1)、提高内聚和松耦合

    2)、父类中无法知道要实例化哪个具体的子类(具体看下面)

    这里引出了factory模式的两个重要功能:

    1)定义创建对象的接口,封装了对象的创建;
    2)使得具体化类的工作延迟到了子类中。

    我们可以看出,第二个图的结构解决了第一个问题,即它使得我们能够规范的使用一个接口来初始化类,我们想象一下,为了达到多态,我们经常抽象出一个基类,然后很多不同的子类指向这个基类,这样我们在需要创建子类的对象的时候我们就必须知道具体的子类的名字,这样带来很多问题,如名称多而乱等,还有可拓展性问题。但有一个相同的接口的话,接口内部的修改不影响用户,可拓展性增强了,而且用户无需知道具体的子类的名字就可以创建对象了。

    但是,第二个图的结构无法解决第二个问题。第二个图的模式只有一种基类。那么这时我们就要用到第一个图所显示的AbstractFactory 模式了。

    AbstractFactory 模式通过将一组对象的额创建封装到一个用于创建对象的类(ConcreteFactory)中,这样,我们可以根据不同的ConcreteFactory类来实例化不同类型的子对象。并且,维护这样一个创建类总比维护n多相关对象的创建过程要简单的多。

    下面我们来看看具体的代码实现:

     1 //Product.h
     2 
     3 #ifndef PRODUCT_H
     4 #define PRODUCT_H
     5 
     6 class AbstractProductA{
     7 public:
     8     virtual ~AbstractProductA();
     9 protected:
    10     AbstractProductA();
    11 private:
    12 };
    13 
    14 class AbstractProductB 
    15 { 
    16 public: 
    17     virtual ~AbstractProductB(); 
    18 protected: 
    19     AbstractProductB(); 
    20 private: 
    21 };
    22 
    23 class ProductA1: public AbstractProductA{
    24 public: 
    25     ProductA1();
    26     ~ProductA1();
    27 protected: 
    28 private:     
    29 };
    30 
    31 class ProductA2:public AbstractProductA 
    32 { 
    33 public: 
    34     ProductA2(); 
    35     ~ProductA2(); 
    36 protected: 
    37 private:
    38 }; 
    39 
    40 class ProductB1: public AbstractProductB{
    41 public: 
    42     ProductB1();
    43     ~ProductB1();
    44 protected: 
    45 private:     
    46 };
    47 
    48 class ProductB2: public AbstractProductB{
    49 public: 
    50     ProductB2();
    51     ~ProductB2();
    52 protected: 
    53 private:     
    54 };
    55 
    56 #endif
     1 //Product.cpp
     2 
     3 #include "Product.h"
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 AbstractProductA::AbstractProductA() {
     9     cout << "AbstractProductA..." << endl;
    10 }
    11 
    12 AbstractProductA::~AbstractProductA() {
    13     cout << "~AbstractProductA..." << endl;
    14 }
    15 
    16 AbstractProductB::AbstractProductB() {
    17     cout << "AbstractProductB..." << endl;
    18 }
    19 
    20 AbstractProductB::~AbstractProductB() {
    21     cout << "~AbstractProductB..." << endl;
    22 }
    23 
    24 ProductA1::ProductA1() {
    25     cout << "ProductA1..." << endl;
    26 }
    27 ProductA1::~ProductA1() {
    28     cout << "~ProductA1..." << endl;
    29 }
    30 
    31 ProductA2::ProductA2() {
    32     cout << "ProductA2..." << endl;
    33 }
    34 ProductA2::~ProductA2() {
    35     cout << "~ProductA2..." << endl;
    36 }
    37 
    38 ProductB1::ProductB1() {
    39     cout << "ProductB1..." << endl;
    40 }
    41 ProductB1::~ProductB1() {
    42     cout << "~ProductB1..." << endl;
    43 }
    44 
    45 ProductB2::ProductB2() {
    46     cout << "ProductB2..." << endl;
    47 }
    48 ProductB2::~ProductB2() {
    49     cout << "~ProductB2..." << endl;
    50 }
     1 //AbstractFactory.h
     2 
     3 #ifndef ABSTRACTFACTORY_H
     4 #define ABSTRACTFACTORY_H
     5 
     6 class AbstractProductA;
     7 class AbstractProductB;
     8 
     9 class AbstractFactory{
    10 public:
    11     virtual ~AbstractFactory();
    12     virtual AbstractProductA* CreateProductA() = 0;
    13     virtual AbstractProductB* CreateProductB() = 0;
    14 protected:
    15     AbstractFactory();
    16 private:
    17 };
    18 
    19 class ConcreteFactory1: public AbstractFactory{
    20 public:
    21     ConcreteFactory1();
    22     ~ConcreteFactory1();
    23     AbstractProductA* CreateProductA();
    24     AbstractProductB* CreateProductB();
    25 protected:
    26 private:
    27 };
    28 
    29 class ConcreteFactory2: public AbstractFactory{
    30 public:
    31     ConcreteFactory2();
    32     ~ConcreteFactory2();
    33     AbstractProductA* CreateProductA();
    34     AbstractProductB* CreateProductB();
    35 protected:
    36 private:
    37 };
    38 
    39 #endif
     1 //AbstractFactory.cpp
     2 
     3 #include "AbstractFactory.h"
     4 #include "Product.h"
     5 #include <iostream>
     6 
     7 using namespace std;
     8 
     9 AbstractFactory::AbstractFactory() {
    10     cout << "AbstractFactory..." << endl;
    11 }
    12 
    13 AbstractFactory::~AbstractFactory() {
    14     cout << "~AbstractFactory..." << endl;
    15 }
    16 
    17 ConcreteFactory1::ConcreteFactory1() {
    18     cout << "ConcreteFactory1..." << endl;
    19 }
    20 
    21 ConcreteFactory1::~ConcreteFactory1() {
    22     cout << "~ConcreteFactory1..." << endl;
    23 }
    24 
    25 AbstractProductA* ConcreteFactory1::CreateProductA() {
    26     return new ProductA1();
    27 }
    28 AbstractProductB* ConcreteFactory1::CreateProductB() {
    29     return new ProductB1();
    30 }
    31 
    32 ConcreteFactory2::ConcreteFactory2() {
    33     cout << "ConcreteFactory2..." << endl;
    34 }
    35 
    36 ConcreteFactory2::~ConcreteFactory2() {
    37     cout << "~ConcreteFactory2..." << endl;
    38 }
    39 
    40 AbstractProductA* ConcreteFactory2::CreateProductA() {
    41     return new ProductA2();
    42 }
    43 AbstractProductB* ConcreteFactory2::CreateProductB() {
    44     return new ProductB2();
    45 }
     1 //main.cpp
     2 
     3 #include"AbstractFactory.h" 
     4 #include<iostream>
     5 
     6 using namespace std;
     7 
     8 int main(int argc,char*argv[])
     9 { 
    10     AbstractFactory* concretefactory1  = new ConcreteFactory1(); 
    11     concretefactory1->CreateProductA(); 
    12     concretefactory1->CreateProductB(); 
    13 
    14     AbstractFactory* concretefactory2  = new ConcreteFactory2(); 
    15     concretefactory2->CreateProductA(); 
    16     concretefactory2->CreateProductB(); 
    17     return 0;
    18 } 

    运行结果:

    AbstractFactory...
    ConcreteFactory1...
    AbstractProductA...
    ProductA1...
    AbstractProductB...
    ProductB1...
    AbstractFactory...
    ConcreteFactory2...
    AbstractProductA...
    ProductA2...
    AbstractProductB...
    ProductB2...
    请按任意键继续. . .
  • 相关阅读:
    竞品选择的背后
    小程序UI
    效果CSS实现三角
    pmp心得
    [已读]响应式web设计实践
    [在读]HTML5程序设计(第二版)
    [已读]响应式web设计
    [已读]HTML5与CSS3权威指南第二版(下)
    [已读]编写可维护的javascript
    [未读]JavaScript高效图形编程
  • 原文地址:https://www.cnblogs.com/xiezhw3/p/3545177.html
Copyright © 2020-2023  润新知