• Abstract Factory(抽象工厂)模式


    1.意图

        提供一个创建一系列相关或相互依赖对象的接口,而无需制定它们具体的类。

    2.适用性

    •  一个系统要独立于它的产品创建、组合和表示时。
    • 一个系统要由多个产品系列中的一个来配置时。
    • 当你强调一系列相关的产品对象的设计以便进行联合使用时。
    • 当你提供一个产品的类库,而只想显示它们的接口而不是实现时。

    3.结构图

        如上图所示为抽象工厂的结构图,每一个工厂负责创建一系列产品。

    4.C++代码实例

    #include <cstdlib>
    #include <string>
    class AbstractFactory;
    
    class Client
    {
    public:
        Client(){};
        ~Client(){};
        AbstractFactory *GetFactory(std::string type);
    private:
        AbstractFactory *pFactory;
    
    };
    Client.h
     1 class AbstractProductA
     2 {
     3 public:
     4     AbstractProductA()
     5     {
     6     }
     7     virtual ~AbstractProductA()
     8     {
     9     };
    10 };
    11 
    12 
    13 class AbstractProductB
    14 {
    15 public:
    16     AbstractProductB()
    17     {
    18     }
    19     virtual ~AbstractProductB()
    20     {
    21     };
    22 };
    AbstractProduct
     1 class AbstractProductA;
     2 class AbstractProductB;
     3 
     4 class AbstractFactory
     5 {
     6 public:
     7      AbstractFactory()
     8      {
     9      };
    10      ~AbstractFactory(){};
    11     virtual AbstractProductA * CreateProductA()=0;
    12     virtual AbstractProductB * CreateProductB()=0;
    13 };
    AbstractFactory
     1 #include "AbstractFactory.h"
     2 
     3 class AbstractProductA;
     4 class AbstractProductB;
     5 
     6 class ConcreteFactory1 : public AbstractFactory
     7 {
     8 public:
     9     ConcreteFactory1();
    10     ~ConcreteFactory1();
    11     AbstractProductA * CreateProductA();
    12     AbstractProductB * CreateProductB();
    13 };
    14 
    15 class ConcreteFactory2 : public AbstractFactory
    16 {
    17 public:
    18     ConcreteFactory2();
    19     ~ConcreteFactory2();
    20     AbstractProductA * CreateProductA();
    21     AbstractProductB * CreateProductB();
    22 };
    ConcreteFactory
     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <iostream>
     4 #include "AbstractProduct.h"
     5 
     6 class ConcreteProductA1 : public AbstractProductA
     7 {
     8 public:
     9     ConcreteProductA1()
    10     {
    11         std::cout << "ConcreteProductA1 is Created" << std::endl;
    12     }
    13     ~ConcreteProductA1()
    14     {
    15     }
    16 };
    17 
    18 class ConcreteProductA2 : public AbstractProductA
    19 {
    20 public:
    21     ConcreteProductA2()
    22     {
    23         std::cout << "ConcreteProductA2 is Created" << std::endl;
    24     }
    25     ~ConcreteProductA2()
    26     {
    27     }
    28 };
    29 
    30 class ConcreteProductB1 : public AbstractProductB
    31 {
    32 public:
    33     ConcreteProductB1()
    34     {
    35         std::cout << "ConcreteProductB1 is Created" << std::endl;
    36     }
    37 
    38     ~ConcreteProductB1()
    39     {
    40     }
    41     
    42 };
    43 
    44 class ConcreteProductB2 : public AbstractProductB
    45 {
    46 public:
    47     ConcreteProductB2()
    48     {
    49         std::cout << "ConcreteProductB2 is Created" << std::endl;
    50     }
    51 
    52     ~ConcreteProductB2()
    53     {
    54     }
    55 };
    ConcereteProduct
    #include "ConcreteFactory.h"
    #include "ConcreteProduct.h"
    
    
    
    ConcreteFactory1::ConcreteFactory1()
    {
    }
    
    ConcreteFactory1::~ConcreteFactory1()
    {
    }
    
    AbstractProductA * ConcreteFactory1::CreateProductA()
    {
        auto product = new ConcreteProductA1();
        return product;
    }
    
    AbstractProductB * ConcreteFactory1::CreateProductB()
    {
        auto product = new ConcreteProductB1();
        return product;
    }
    
    
    ConcreteFactory2::ConcreteFactory2()
    {
    }
    
    ConcreteFactory2::~ConcreteFactory2()
    {
    }
    
    AbstractProductA * ConcreteFactory2::CreateProductA()
    {
        auto product = new ConcreteProductA2();
        return product;
    }
    
    AbstractProductB * ConcreteFactory2::CreateProductB()
    {
        auto product = new ConcreteProductB2();
        return product;
    }
    ConcreteFactory.cpp
    #include "Client.h"
    #include "ConcreteFactory.h"
    
     AbstractFactory *Client::GetFactory(std::string type)
     {
         if("1" == type)
         {
             auto pFactory = new ConcreteFactory1();
             return pFactory;
         }
         else if ("2" == type)
         {
             auto pFactory = new ConcreteFactory2();
             return pFactory;
         }
     }
    Client.cpp
    #include "Client.h"
    #include "AbstractFactory.h"
    #include "AbstractProduct.h"
    
    int main()
    {
        auto client = new Client();
        auto pFactory = client->GetFactory("1");
        auto pProductA = pFactory->CreateProductA();
        auto pProductB = pFactory->CreateProductB();
        delete pProductB;
        pProductB = NULL;
        delete pProductA;
        pProductA = NULL;
        delete pFactory;
        pFactory = NULL;
    
        pFactory = client->GetFactory("2");
        pProductA = pFactory->CreateProductA();
        pProductB = pFactory->CreateProductB();
        delete pProductB;
        pProductB = NULL;
        delete pProductA;
        pProductA = NULL;
        delete pFactory;
        pFactory = NULL;
        delete client;
        client=NULL;
    
        while(1);
        
    
    }
    TestCode.cpp

    测试结果:

    如测试代码中所写,先创建1系列的产品A和B,后创建2系列的产品A和B。

    5.效果

    • 分离了具体的类,产品的类名不出现在测试代码(即客户代码)中。
    • 使得易于交换产品系列。
    • 利于产品的一致性。
    • 难以支持新种类的产品

    6.相关模式

    抽象工厂类通常用工厂方法实现,但是也可以用原型实现。一个具体的工厂通常是一个单件。

     

  • 相关阅读:
    《House of Cards》观后感
    几个常见的壳的脱壳
    【转】Arp的攻防实战
    Back Track 5 之 漏洞攻击 && 密码攻击 && Windows下渗透工具
    Back Track 5 之 Web踩点 && 网络漏洞
    Back Track 5 之 网络踩点(二)
    Back Track 5 之 网络踩点
    51单片机总线与非总线的程序对比
    关于PHP写的投票网站之刷票终结版
    关于PowerShell中的命令的别名
  • 原文地址:https://www.cnblogs.com/mgp200866130/p/5398528.html
Copyright © 2020-2023  润新知