• [原创]设计模式抽象工厂模式


    抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据LSP原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例。

    定义

    为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类

    简介

    当每个抽象产品都有多于一个的具体子类的时候,工厂角色怎么知道实例化哪一个子类呢?比如每个抽象产

      抽象工厂模式类图

    产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。
    每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结构。

    产品族

    是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。叫做相图。
    当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这三个产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。
    抽象工厂模式使用同一个 工厂等级结构负责三个不同产品等级结构产品对象的创建。
    对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。
    通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。
    由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。

    使用情况

    1.系统不依赖于产品类实例如何被创建,组合和表达的细节。
    2.系统的产品有多于一个的产品族,而系统只消费其中某一族的产品(抽象工厂模式的原始用意Unix&Windows)
    Button--->UnixButton/WinButton
    Text----->UnixText/WinText
    Unix产品族和Windows产品族,不会同时使用。
    Factory--->UnixFactory/WinFactory
    3.同属于同一个产品族是在一起使用的。这一约束必须在系统的设计中体现出来。
    4.系统提供一个产品类的库,所有产品以同样的接口出现,从而使客户端不依赖于实现。
    C++实现:
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    
    using namespace std;
    
    //CPU
    class CPU
    {
    public:
        virtual void show() = 0;
    };
    
    class macCPU : public CPU
    {
    public:
        void show()
        {
            cout << "show mac cpu" << endl;
        }
    };
    
    class pcCPU : public CPU
    {
    public:
        void show()
        {
            cout << "show pc cpu" << endl;
        }
    };
    //内存
    class Ram
    {
    public:
        virtual void show() = 0;
    };
    
    class macRam : public Ram
    {
    public:
        void show()
        {
            cout << "show mac ram" << endl;
        }
    };
    
    class pcRam : public Ram
    {
    public:
        void show()
        {
            cout << "show pc ram" << endl;
        }
    };
    //抽象工厂
    class AbstractFactory
    {
    public:
        virtual CPU *CreateCPU() = 0;
        virtual Ram *CreateRam() = 0;
    };
    //具体的工厂
    //mac工厂
    class MacFactory : public AbstractFactory
    {
    public:
        CPU *CreateCPU()
        {
            return new macCPU();
        }
        Ram *CreateRam()
        {
            return new macRam();
        }
    };
    //pc工厂
    class PCFactory : public AbstractFactory
    {
    public:
        CPU *CreateCPU()
        {
            return new pcCPU();
        }
        Ram *CreateRam()
        {
            return new pcRam();
        }
    };

    客户端调用代码:

    #include "stdafx.h"
    #include "AbstractFactory.h"
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        AbstractFactory *macFactory = new MacFactory();
        AbstractFactory *pcFactory = new PCFactory();
    
        CPU *cpu1 = macFactory->CreateCPU();
        Ram *ram1 = macFactory->CreateRam();
        cpu1->show();
        ram1->show();
    
        CPU *cpu2 = pcFactory->CreateCPU();
        Ram *ram2 = pcFactory->CreateRam();
        cpu2->show();
        ram2->show();
    
        delete cpu1, ram2, cpu2, ram2;
        delete macFactory, pcFactory;
    
        getchar();
        return 0;
    }

    使用抽象工厂,可以派生出许多不同的产品族,每增加一个产品族,只需要派生出一个子工厂类即可。

    转载请注明出处:http://qq78292959.cnblogs.com/

  • 相关阅读:
    mysql分表和表分区详解
    CNN 文本分类
    基于深度学习的目标检测研究进展
    标注工具
    在Ubuntu登陆界面输入密码之后,黑屏一闪后,又跳转到登录界面
    R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列深度学习检测方法梳理
    LeNet,AlexNet,GoogleLeNet,VggNet等网络对比
    nginx使用与配置入门指南
    CentOS 7上重新编译安装nginx
    酸汤肉沫豆腐
  • 原文地址:https://www.cnblogs.com/qq78292959/p/2916949.html
Copyright © 2020-2023  润新知