C++常见三种工厂设计模式

设计模式

简单工厂模式

  • 简单工厂模式:主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类。

  • 使用场景

    工厂类负责创建的对象比较少;

    客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;

    由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

  • 代码

    //算法的父类,抽象出返回结果的接口
    class Operation
    {
    public:
        virtual int GetResult() =0;
    public:
        double m_Num1;
        double m_Num2;
    };
    //工厂类,用于生产相应的算法子类
    class OperationFactry
    {
    public:
        OperationFactry(void);
        ~OperationFactry(void);
    public:
        static Operation* CreateOperate(int n )
        {
            switch(n)
            {
            case 1:
                return new OperationAdd;
                break;
            }
        }
    };
    //算法子类,由工厂类创建,重写父类中的虚函数
    class OperationAdd:Public Operation
    {
    public:
        int GetResult();
    };
    

工厂方法模式

  • 工厂方法模式

    • 是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品。

    • 工厂方法模式对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不再负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

  • 角色结构

    • 抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。

    • 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。在上图中有两个这样的角色:BulbCreator与TubeCreator。

    • 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在上图中,这个角色是Light。

    • 具体产品(Concrete Product)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。

  • 代码

    //抽象产品角色
    class Tank
    {
    public:
        virtual void message() = 0;
    };
    
    //具体的产品类
    class Tank80:public Tank
    {
    public:
        void message()
        {
            cout << "Tank80" << endl;
        }
    };
    
    class Tank99:public Tank
    {
    public:
        void message()
        {
            cout << "Tank99" << endl;
        }
    };
    
    //抽象工厂角色
    class TankFactory
    {
    public:
        virtual Tank* createTank() = 0;
    };
    
    //具体的工厂类
    class Tank80Factory:public TankFactory
    {
    public:
        Tank* createTank()
        {
            return new Tank80();
        }
    };
    
    class Tank99Factory:public TankFactory
    {
    public:
        Tank* createTank()
        {
            return new Tank99();
        }
    };
    
    int main()
    {
        TankFactory* factory80 = new Tank80Factory;
        Tank* tank80 = factory80->createTank();
        tank80->message();
        return 0;
    }
    

抽象工厂模式

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

  • 产品族

    • 是指位于不同产品等级结构中,功能相关联的产品组成的家族。一般是位于不同的等级结构中的相同位置上。显然,每一个产品族中含有产品的数目,与产品等级结构的数目是相等的,形成一个二维的坐标系,水平坐标是产品等级结构,纵坐标是产品族。叫做相图。
    • 当有多个不同的等级结构的产品时,如果使用工厂方法模式就势必要使用多个独立的工厂等级结构来对付这些产品的等级结构。如果这些产品等级结构是平行的,会导致多个平行的工厂等级结构。
    • 抽象工厂模式使用同一个 工厂等级结构负责这些不同产品等级结构产品对象的创建。
    • 对于每一个产品族,都有一个具体工厂。而每一个具体工厂创建属于同一个产品族,但是分属于不同等级结构的产品。
    • 通过引进抽象工厂模式,可以处理具有相同(或者相似)等级结构的多个产品族中的产品对象的创建问题。
    • 由于每个具体工厂角色都需要负责两个不同等级结构的产品对象的创建,因此每个工厂角色都需要提供两个工厂方法,分别用于创建两个等级结构的产品。既然每个具体工厂角色都需要实现这两个工厂方法,所以具有一般性,不妨抽象出来,移动到抽象工厂角色中加以声明。
  • **常用场景:**一件产品有很多个组件组成,与之类似的产品还有很多。每个产品与组件是一一对应的关系。类如一个药品公司生产的口服药剂,现在有A,B,C三种口服药剂,这三个口服药剂都有各自的药水、说明书、包装盒。A,B,C对应的就是产品族的概念,药水和说明书,包装盒就是组件的概念。

  • 代码: 数据库访问程序设计,不同的数据库访问方式可能不一样,为了抽象对不同数据库的访问,可以将数据库隐藏起来,提供统一的访问方式,用多态进行实现。

    #include <iostream>
    using namespace std;
    //用户表接口
    class IUser
    {
    public:
    	virtual void Insert() = 0;
    	virtual void GetUser() = 0;
    };
    //SqlServer数据库访问User表
    class SqlServerUser : public IUser
    {
    public:
    	void Insert()
    	{
    		cout << "在SQL Server中给User表增加一条记录" << endl;
    	}
    	void GetUser()
    	{
    		cout << "在SQL Server中给User表获取一条记录" << endl;
    	}
    };
    //Access数据库访问User表
    class AccessUser : public IUser
    {
    public:
    	void Insert()
    	{
    		cout << "在Access中给User表增加一条记录" << endl;
    	}
    	void GetUser()
    	{
    		cout << "在Access中User表获取一条记录" << endl;
    	}
    };
    //Department表接口
    class IDepartment
    {
    public:
    	virtual void Insert() = 0;
    	virtual void GetDepartment() = 0;
    };
    //SqlServer数据库访问Department表
    class SqlServerDepartment : public IDepartment
    {
    public:
    	void Insert()
    	{
    		cout << "在SQL Server中给Department表增加一条记录" << endl;
    	}
    	void GetDepartment()
    	{
    		cout << "在SQL Server中Department获取一条记录" << endl;
    	};
    };
    //Access数据库访问Department表
    class AccessDepartment : public IDepartment
    {
    public:
    	void Insert()
    	{
    		cout << "在Access中给Department表增加一条记录" << endl;
    	}
    	void GetDepartment()
    	{
    		cout << "在Access中Department获取一条记录" << endl;
    	};
    };
    //抽象工厂接口
    class IFactory
    {
    public:
    	virtual IUser* CreateUser() = 0;
    	virtual IDepartment* CreateDepartment() = 0;
    };
    //SqlServer工厂实现
    class SqlServerFactory : public IFactory
    {
    	IUser* CreateUser()
    	{
    		return new SqlServerUser();
    	}
    	IDepartment* CreateDepartment()
    	{
    		return new SqlServerDepartment();
    	}
    };
    //Access工厂实现
    class AccessFactory : public IFactory
    {
    	IUser* CreateUser()
    	{
    		return new AccessUser();
    	}
    	IDepartment* CreateDepartment()
    	{
    		return new AccessDepartment();
    	}
    };
    int main()
    {
    	//创建工厂
    	IFactory * pFactory = NULL;
    	IUser * pUser = NULL;
    	IDepartment * pDepartment = NULL;
    	int choise;
    	cout << "选择数据库: ";
    	cin >> choise;
    	switch (choise)
    	{
    	case 1:
    		pFactory = new SqlServerFactory(); //创建SqlServer访问的工厂
    		break;
    	case 2:
    		pFactory = new AccessFactory(); //创建Access访问的工厂
    		break;
    	}
    	//一致的操作
    	pUser = pFactory->CreateUser();
    	pDepartment = pFactory->CreateDepartment();
    	pUser->Insert();
    	pUser->GetUser();
    	pDepartment->Insert();
    	pDepartment->GetDepartment();
    	return 0;
    }
    
    

    版权申明:未经博主同意,禁止转载。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值