C++设计模式:AbstactFactory 模式(抽象工厂模式)

假如我们要买水果,水果的产地来自中国、日本、美国,每个国家的水果种类都可以分为苹果、香蕉、梨子。

作为开发者,我们就不得不创建苹果类(香蕉和梨子类似),然后每种苹果都继承自苹果类。每上架一个国家的苹果我们都要实现一次苹果类,这样就会有成千上万的苹果类需要被创建,AbstractFactory 模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。
举例:

a3b3fc2f11164a6aa7838dc4b856a215.png

代码:

//product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_

#include <iostream>
using namespace std;


//苹果的抽象
class AbstractApple
{
public:

    //务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
    virtual ~AbstractApple()
    {
        cout<<"~AbstractApple"<<endl;
    };

    virtual void showName() = 0;
};


//中国苹果
class ChinaApple:public AbstractApple
{
public:

    ~ChinaApple()
    {
        cout<<"~ChinaApple"<<endl;
    };

    virtual void showName()
    {
        cout<<"中国苹果"<<endl;
    }
};

//美国苹果
class UsaApple:public AbstractApple
{
public:
    virtual void showName()
    {
        cout<<"美国苹果"<<endl;
    }
};

//日本苹果
class JapanApple:public AbstractApple
{
public:
    virtual void showName()
    {
        cout<<"日本苹果"<<endl;
    }
};


//香蕉的抽象
class AbstractBanana
{
public:

    //务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
    virtual ~AbstractBanana()
    {
        cout<<"~AbstractBanana"<<endl;
    };

    virtual void showName() = 0;
};

//中国香蕉
class ChinaBanana:public AbstractBanana
{
public:

    ~ChinaBanana()
    {
        cout<<"~ChinaBanana"<<endl;
    };

    virtual void showName()
    {
        cout<<"中国香蕉"<<endl;
    }
};

//美国香蕉
class UsaBanana:public AbstractBanana
{
public:
    virtual void showName()
    {
        cout<<"美国香蕉"<<endl;
    }
};

//日本香蕉
class JapanBanana:public AbstractBanana
{
public:
    virtual void showName()
    {
        cout<<"日本香蕉"<<endl;
    }
};


//鸭梨的抽象
class AbstractPear
{
public:

    //务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
    virtual ~AbstractPear()
    {
        cout<<"~AbstractPear"<<endl;
    };

    virtual void showName() = 0;
};

//中国鸭梨
class ChinaPear:public AbstractPear
{
public:

    ~ChinaPear()
    {
        cout<<"~ChinaPear"<<endl;
    };

    virtual void showName()
    {
        cout<<"中国鸭梨"<<endl;
    }
};

//美国鸭梨
class UsaPear:public AbstractPear
{
public:
    virtual void showName()
    {
        cout<<"美国鸭梨"<<endl;
    }
};

//日本鸭梨
class JapanPear:public AbstractPear
{
public:
    virtual void showName()
    {
        cout<<"日本鸭梨"<<endl;
    }
};


#endif // _PRODUCT_H_

//factory.h
#ifndef _FACTORY_H_
#define _FACTORY_H_

#include <iostream>
#include "product.h"

using namespace std;


//工厂的抽象
class AbstractFactory
{
public:

    //务必定义虚析构函数,否则销毁派生类对象时,基类指针直接析构基类,导致派生类对象销毁不完整
    virtual ~AbstractFactory()
    {
        cout<<"~AbstractFactory"<<endl;
    };

    virtual AbstractApple* CreateApple() = 0;
    virtual AbstractBanana* CreateBanana() = 0;
    virtual AbstractPear* CreatePear() = 0;
};

//中国工厂,可生产中国版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class ChinaFactory:public AbstractFactory
{
    ~ChinaFactory()
    {
        cout<<"~ChinaFactory"<<endl;
    };

    virtual AbstractApple* CreateApple()
    {
        return new ChinaApple;
    }

    virtual AbstractBanana* CreateBanana()
    {
        return new ChinaBanana;
    }

    virtual AbstractPear* CreatePear()
    {
        return new ChinaPear;
    }
};

//美国工厂,可生产美国版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class UsaFactory:public AbstractFactory
{
    virtual AbstractApple* CreateApple()
    {
        return new UsaApple;
    }

    virtual AbstractBanana* CreateBanana()
    {
        return new UsaBanana;
    }

    virtual AbstractPear* CreatePear()
    {
        return new UsaPear;
    }
};

//日本工厂,可生产日本版苹果香蕉和梨(派生类),返回的是苹果香蕉和梨的基类
class JapanFactory:public AbstractFactory
{
    virtual AbstractApple* CreateApple()
    {
        return new JapanApple;
    }

    virtual AbstractBanana* CreateBanana()
    {
        return new JapanBanana;
    }

    virtual AbstractPear* CreatePear()
    {
        return new JapanPear;
    }
};


#endif // _FACTORY_H_

//main.c
#include <iostream>
#include "factory.h"
#include "product.h"

using namespace std;


int main()
{
    AbstractFactory *factory_ptr = NULL;
    AbstractApple     *apple_ptr = NULL;
    AbstractBanana   *banana_ptr = NULL;
    AbstractPear       *pear_ptr = NULL;

    //中国工厂,生产中国版的水果
    factory_ptr = new ChinaFactory;
    apple_ptr = factory_ptr->CreateApple();
    banana_ptr = factory_ptr->CreateBanana();
    pear_ptr = factory_ptr->CreatePear();

    //调用中国版水果的接口
    apple_ptr->showName();
    banana_ptr->showName();
    pear_ptr->showName();

    delete pear_ptr;
    delete apple_ptr;
    delete banana_ptr;
    delete factory_ptr;

    return 0;
}



运行结果:

86f6147018064a15b1824e27eda7acee.png

总结:

AbstractFactory 模式和 Factory模式的区别是初学设计模式时候的一个容易引起困惑的地方。

实际上,AbstractFactory模式是为创建一系列相关的对象提供创建接口,而 Factory模式是为某一类对象提供创建接口或延迟对象的创建到子类中实现。并且可以看到,AbstractFactory模式通常都是使用 Factory 模式实现。

抽象工厂模式关注于创建一系列相关的产品对象,如果需要添加新的产品族,则需要定义新的工厂类并实现具体的某个Factory接口。

抽象工厂模式和工厂模式的区别:

相同点

  • 两者都是创建型设计模式,用于创建对象。
  • 两者都提供了对客户端隐藏具体实现细节的好处,客户端只需要知道接口或抽象类型。

不同点

  • 对象创建范围和灵活性:工厂模式主要用于创建单个对象,而抽象工厂模式可以创建多个复杂对象。当需要创建多个对象时,使用抽象工厂模式可以更加灵活地满足需求。另外,抽象工厂模式中不同的工厂方法可以有不同的实现,从而进一步提高对象创建的灵活性。
  • 可维护和可扩展性:工厂模式在添加新产品时,通常只需要修改工厂类。而抽象工厂模式在添加新产品族时,需要定义新的工厂类和一系列新的产品类。虽然工厂模式简单直观,但随着需求的增加,可能需要修改或扩展工厂类,这可能导致代码的维护变得困难。而抽象工厂模式虽然比工厂模式复杂,但可以提供更多的抽象和封装,使得代码更加模块化,从而提高了代码的可维护性和可扩展性。
  • 复杂度和聚合程度:抽象工厂模式比工厂模式更复杂,因为它涉及更多的接口和类。工厂模式通常只创建一个对象,而抽象工厂模式创建的对象较多,聚合程度较高。因此,如果需要创建聚合程度较高的对象,使用抽象工厂模式可以更好地实现。

抽象工厂模式和工厂模式在对象创建的范围、扩展性和复杂度方面存在显著的差异。在选择使用哪种模式时,需要根据具体的应用场景和需求来权衡。在简单的对象创建场景下,工厂模式可能更为适合;而在需要创建多个复杂对象,且希望提高代码的可维护性和可扩展性的情况下,抽象工厂模式可能更为理想。

靠谱推荐:Free Pos,微信JOCIHEZ

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值