zoukankan      html  css  js  c++  java
  • 设计模式之抽象工厂模式

    一、概述

    ###抽象工厂模式,以一个鞋业代理工厂为例(可代理生产Nike,Adidas的鞋子)
    ConcreteFactory1, ConcreteFactory2 这里对实例工厂的分类,每一个实例工厂对应一可以看做是生产同一系列(品种)下的产品,
                                        举例:前者代表Nike鞋工厂类,后者代表Adidas鞋工厂类。
    ConcreteProductA, ConcreteProductB 这里对实例产品的分类,每一个实例产品可以看做是不同系列的产品集合,
                                        如:分别代表各式鞋子,分别代表布鞋(派生出nike布鞋,adidas布鞋)和皮鞋(派生出nike皮鞋,adidas皮鞋)
    1,2,3......代表品种(系列):如NIKE, ADIDAS
    A,B,C......代表产品,其派生类可延伸出各种品种(系列)下的产品,如布鞋,皮鞋

    说明:
    工厂模式下,对管理的产品没有做进一步的分类,获取所有产品的返回值都是它们的虚基类,只能看做是对某一类类的操作。
    而抽象工厂模式,则对产品进行规划的基础上,又再次细分成产品系列;对工厂类也做了扩展,返回不再是产品的公共虚基类,而是产品所在系列的基类。
    这正如一家鞋业代理工厂要生产鞋子一样,如果它代理10家的品牌,这10家品牌都从一个码头出货,哇咔咔,出货码头人来人往,货来货往,好像有点堵哦。
    而抽象工厂将产品划分到系列,为每个系列定义接口,这样一来,每个品牌的鞋子都有自己的通道来接货,各品牌之间相互独立,码头也变得井然有序了。


    ###工厂模式
    ConcreteFactory1 :生产(new)多个产品,返回产品的虚基类。
    ConcreteProductA :最终产品,基于虚基类

    ###抽象工厂模式
    ConcreteFactory1 : 生产(new)本系列的多个产品,而且同款产品会存在多个系列,
    ConcreteProductA : 中间产品,上基于虚基类,下派生不同系列下的同款产品

    优点:新增系列产品,只需要新增一个工厂即可。
    缺点:新增某一新产品时,就变得困难了

    总结:
        抽象工厂不仅对产品类做了规划,同时也对工厂类做了改善。具体表现为:对产品的规划变成了3层结构:产品虚基类-产品系列子类-产品子类;工厂仍保持2层结构,但在第2层做了扩展:工厂虚基类-创建产品系列子类

        我们前面说过,标准工厂的做法就是定义一个创建所有产品的公共接口,供工厂派生类使用。
        当产品过多时,使用标准工厂就有些力不从心,因为这些产品都来自于同一个接口,是非常不利于管理的。


    二、类图

    三、代码

    IProduct.h, IProduct.cpp (见简单工厂模式)

    ConcreteProductA.h, ConcreteProductA.cpp (同上)

    ConcreteProductB.h, ConcreteProductB.cpp (同上)

    ConcreteProductA1.h  //产品A: 系列1下的产品A

    #pragma once
    #include "ConcreteProductA.h"
    
    class CConcreteProductA1 :public CConcreteProductA
    {
    public:
    	CConcreteProductA1();
    	virtual ~CConcreteProductA1();
    
    public:
    	virtual void Function();
    
    };
    

     ConcreteProductA1.cpp

    #include "ConcreteProductA1.h"
    
    CConcreteProductA1::CConcreteProductA1()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    CConcreteProductA1::~CConcreteProductA1()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    void CConcreteProductA1::Function()
    {
    	cout<<__FUNCTION__<<endl;
    }
    

    ConcreteProductA2.h

    #pragma once
    #include "ConcreteProductA.h"
    
    class CConcreteProductA2 :public CConcreteProductA
    {
    public:
    	CConcreteProductA2();
    	virtual ~CConcreteProductA2();
    
    public:
    	virtual void Function();
    
    };
    

    ConcreteProductA2.cpp

    #include "ConcreteProductA2.h"
    
    CConcreteProductA2::CConcreteProductA2()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    CConcreteProductA2::~CConcreteProductA2()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    void CConcreteProductA2::Function()
    {
    	cout<<__FUNCTION__<<endl;
    }
    

    ConcreteProductB1.h

    #pragma once
    #include "ConcreteProductB.h"
    
    class CConcreteProductB1 :public CConcreteProductB
    {
    public:
    	CConcreteProductB1();
    	virtual ~CConcreteProductB1();
    
    public:
    	virtual void Function();
    
    };
    

    ConcreteProductB1.cpp

    #include "ConcreteProductB1.h"
    
    CConcreteProductB1::CConcreteProductB1()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    CConcreteProductB1::~CConcreteProductB1()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    void CConcreteProductB1::Function()
    {
    	cout<<__FUNCTION__<<endl;
    }
    

    ConcreteProductB2.h

    #pragma once
    #include "ConcreteProductB.h"
    
    class CConcreteProductB2 :public CConcreteProductB
    {
    public:
    	CConcreteProductB2();
    	virtual ~CConcreteProductB2();
    
    public:
    	virtual void Function();
    
    };
    

    ConcreteProductB2.cpp

    #include "ConcreteProductB2.h"
    
    CConcreteProductB2::CConcreteProductB2()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    CConcreteProductB2::~CConcreteProductB2()
    {
    	cout<<__FUNCTION__<<endl;
    }
    
    void CConcreteProductB2::Function()
    {
    	cout<<__FUNCTION__<<endl;
    }
    

    IAbstractFactory.h

    #pragma once
    
    //抽象工厂类要创建多个系列产品,所以要#include产品系列的类进来
    #include "ConcreteProductA.h"
    #include "ConcreteProductB.h"
    
    
    class IAbstractFactory
    {
    public:
    	IAbstractFactory();
    	virtual ~IAbstractFactory();
    
    public:
    	virtual CConcreteProductA *CreateA() = 0;
    	virtual CConcreteProductB *CreateB() = 0;
    };
    

    IAbstractFactory.cpp

    #include "IAbstractFactory.h"
    
    IAbstractFactory::IAbstractFactory()
    {
    
    }
    
    IAbstractFactory::~IAbstractFactory()
    {
    
    }
    

    ConcreteAbsFactory1.h

    #pragma once
    
    #include "IAbstractFactory.h" 
    
    //应该放在cpp文件里面
    #include "ConcreteProductA1.h"
    #include "ConcreteProductB1.h"
    //工厂派生类1:创建某一系列下的产品,
    class CConcreteAbsFactory1 :public IAbstractFactory
    {
    public:
    	CConcreteAbsFactory1();
    	virtual ~CConcreteAbsFactory1();
    
    public:
    	virtual CConcreteProductA *CreateA();
    	virtual CConcreteProductB *CreateB();
    };
    

    ConcreteAbsFactory1.cpp

    #include "ConcreteAbsFactory1.h"
    
    CConcreteAbsFactory1::CConcreteAbsFactory1()
    {
    
    }
    
    CConcreteAbsFactory1::~CConcreteAbsFactory1()
    {
    
    }
    
    
    CConcreteProductA *CConcreteAbsFactory1::CreateA()
    {
    	return new CConcreteProductA1();
    }
    
    CConcreteProductB *CConcreteAbsFactory1::CreateB()
    {
    	return new CConcreteProductB1();
    }
    

    ConcreteAbsFactory2.h

    #pragma once
    
    #include "IAbstractFactory.h" 
    
    //应该放在cpp文件里面
    #include "ConcreteProductA2.h"
    #include "ConcreteProductB2.h"
    //工厂派生类2:创建某一系列下的产品,
    class CConcreteAbsFactory2 :public IAbstractFactory
    {
    public:
    	CConcreteAbsFactory2();
    	virtual ~CConcreteAbsFactory2();
    
    public:
    	virtual CConcreteProductA *CreateA();
    	virtual CConcreteProductB *CreateB();
    };
    

    ConcreteAbsFactory2.cpp

    #include "ConcreteAbsFactory2.h"
    
    CConcreteAbsFactory2::CConcreteAbsFactory2()
    {
    
    }
    
    CConcreteAbsFactory2::~CConcreteAbsFactory2()
    {
    
    }
    
    
    CConcreteProductA *CConcreteAbsFactory2::CreateA()
    {
    	return new CConcreteProductA2();
    }
    
    CConcreteProductB *CConcreteAbsFactory2::CreateB()
    {
    	return new CConcreteProductB2();
    }
    

     main.cpp

    #include "ConcreteAbsFactory1.h"
    #include "ConcreteAbsFactory2.h"
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	cout<<"[New ConcreteAbsFactory1]:"<<endl;
    	IAbstractFactory *absfac1 = new CConcreteAbsFactory1();
    	cout<<"[Create Products of 1 serial]:"<<endl; 
    	absfac1->CreateA();
    	absfac1->CreateB();
    
    	cout<<"[New ConcreteAbsFactory2]:"<<endl;
    	IAbstractFactory *absfac2 = new CConcreteAbsFactory2();
    	cout<<"[Create Products of 2 serial]:"<<endl; 
    	absfac2->CreateA();
    	absfac2->CreateB();
    
    	return 0;
    }
    

    四、运行结果

    [New ConcreteAbsFactory1]:
    [Create Products of 1 serial]:
    CConcreteProductA::CConcreteProductA
    CConcreteProductA1::CConcreteProductA1
    CConcreteProductB::CConcreteProductB
    CConcreteProductB1::CConcreteProductB1
    [New ConcreteAbsFactory2]:
    [Create Products of 2 serial]:
    CConcreteProductA::CConcreteProductA
    CConcreteProductA2::CConcreteProductA2
    CConcreteProductB::CConcreteProductB
    CConcreteProductB2::CConcreteProductB2
    请按任意键继续. . .

  • 相关阅读:
    如何下载网络图片资源
    经典排序之快速排序(含红黑树)
    经典排序之归并排序
    node微信公众号开发---自动回复
    koa2的文件上传
    async await的用法
    Generator yield语法和 co模块
    CentOS 7 下安装 Nginx
    windows下nginx的安装及使用方法入门
    linux下nodejs安装以及如何更新到最新的版本
  • 原文地址:https://www.cnblogs.com/jacklikedogs/p/3807728.html
Copyright © 2011-2022 走看看