简单工厂模式的C++实现以及个人理解

目录

前言

简单工厂模式

模式定义

C++实现方法

模式优缺点

应用场景

简单工厂模式常见具体应用

拓展


前言

设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式的目的是为了提高代码的可读性、可维护性和可靠性。

本文是作者在学习《设计模式》课程时,对简单工厂模式、工厂方法模式和抽象工厂模式心存疑惑,在查阅前辈们的博客后,想分享一下自己的个人理解并巩固学习成果,如有错误,欢迎留言指出。

本文主要基于以下方面来讨论简单工厂模式:

  • 模式定义
  • C++实现方法
  • 模式优缺点
  • 应用场景
  • 简单工厂模式常见具体应用
  • 拓展

简单工厂模式

学习简单工厂模式前,我们需要先弄懂“抽象产品类”、“具体产品类”、“工厂类”这三个概念。既然这三个模式都含有“工厂”这个关键词,说明这些设计模式是模仿工厂的设计思想抽象出来的,那我们就把这些概念映射到实际生活中的工厂中。

具体产品类: 它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。

抽象产品类: 它是工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象。

工厂类: 它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象。

比如,以手机为例,手机(Phone)是所有不同品牌手机的抽象产品类,他包含了所有手机的共同特征——能打电话、能上网等;而像华为手机(HuaweiPhone)和小米手机(XiaomiPhone)都是手机的具体产品类,分别封装了各自不同的功能和结构;那手机的代加工工厂“富士康(Foxconn)”则是生产手机的工厂,根据不同的设计方案和需求完成各种品牌手机的具体组装任务;最后通过各种渠道销售给我们这些“客户端”使用。

 

模式定义

定义一个工厂类,它可以根据参数的不同返回不同具体产品类的实例,被创建的实例通常都具有共同的父类(抽象产品类)。

C++实现方法

简单工厂模式可以分为普通简单工厂,多方法简单工厂,静态方法简单工厂。

我们将用手机为产品来演示简单工厂的实现方法:

(1)普通简单工厂:

#include <iostream>

using namespace std;

enum PhoneType
{
    Huawei = 1;
    Xiaomi;
};


//手机的抽象产品类
class Phone
{
public:
    virtual void getPhone() = 0; //为具体产品类提供公共接口
    virtual ~Phone(){}
};

//具体产品类:华为手机类
class HuaweiPhone:public Phone
{
public:
    virtual void getPhone()
    {
        cout<<"华为手机"<<endl;
    }
};

//具体产品类:小米手机类
class XiaomiPhone:public Phone
{
public:
    virtual void getPhone()
    {
        cout<<"小米手机"<<endl;
    }
};

//工厂类
class PhoneFactory
{
public:
    virtual Phone* creatPhone(int phonetype)
    {
        Phone *m_phone = NULL;
        switch(phonetype)
        {
        case 1:
            m_phone = new HuaweiPhone(); break;
        case 2:
            m_phone = new XiaomiPhone(); break;
        default:
            break;
        }
        return m_phone;
    }
};

//客户端
int main()
{
    int i = 0;
    PhoneFactory *factory = new PhoneFactory();
    Phone *myphone = NULL;

    cout<<"输入你想要的手机(1/2):"<<endl;
    cin>>i;
    
    //根据需求生产想要的产品
    myphone = factory->creatPhone(i);
    myphone->getPhone();

    delete myphone;
    delete factory;

    system("pause");
    return 0;
}

(2)多方法简单工厂

多方法简单工厂是对普通工厂模式的改进,在普通工厂模式中,如果传递的参数类型出错,则不能正确创建对象,而多方法简单工厂模式是提供多个工厂方法,分别创建不同产品类的对象。

//工厂类
class PhoneFactory
{
public:
    //华为手机的生成方法
    virtual Phone* getHuawei()
    {
        return new HuaweiPhone();
    }
    //小米手机的生成方法
    virtual Phone* getXiaomi()
    {
        return new XiaomiPhone();
    }

}

//客户端
int main()
{
    int i = 0;
    PhoneFactory *factory = new PhoneFactory();
    Phone *myphone = NULL;

    cout<<"输入你想要的手机(1/2):"<<endl;
    cin>>i;
    
    //根据需求生产想要的产品    
    if(i == 1){
        myphone = factory->getHuawei();
    }
    else{
        myphone = factory->getXiaomi();
    }
    
    myphone->getPhone();

    delete myphone;
    delete factory;

    system("pause");
    return 0;
}

(3)静态方法简单工厂

将工厂方法设置为static的,这样就可以不用创建工厂对象,直接调用静态工厂方法。

//工厂类
class PhoneFactory
{
public:
    //静态工厂方法
    static Phone* creatPhone(int phonetype)
    {
        Phone *m_phone = NULL;
        switch(phonetype)
        {
        case 1:
            m_phone = new HuaweiPhone(); break;
        case 2:
            m_phone = new XiaomiPhone(); break;
        default:
            break;
        }
        return m_phone;
    }
};

//客户端
int main()
{
    int i = 0;
    Phone *myphone = NULL;

    cout<<"输入你想要的手机(1/2):"<<endl;
    cin>>i;
    
    //根据需求生产想要的产品
    myphone = PhoneFactory::creatPhone(i);
    myphone->getPhone();

    delete myphone;

    system("pause");
    return 0;
}

 

模式优缺点

主要优点有:

  • 工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离
  • 客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以在一定程度减少使用者的记忆量
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。

主要缺点有:

  • 由于工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
  • 使用简单工厂模式势必会增加系统中类的个数(引入了新的工厂类),增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护,且违背开闭原则
  • 静态简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。

应用场景

  • 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
  • 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。

简单工厂模式常见具体应用

  • 通常在使用word办公软件的时候,会根据需要绘制出饼状图,柱状图,折线图等图形。可以提供一个工厂类,根据用户的选择创建出不同类型的图形。
  • QQ空间背景样式,博客背景样式等都提供了各种风格的样式。提供一个工厂,根据用户选择的具体风格样式,创建出各个不同的背景风格,用来装饰QQ空间。
  • 电影院打折算法: VIP5折、学生票5折、成人票正常收费等打折算法。

拓展

(1)为什么需要简单工厂模式,它有什么好处?

答:如果不使用简单工厂模式,我们需要在客户端的代码内创建对象,当需要创建多个相似的对象时,我们的客户端代码的可读性就会降低,毕竟客户端代码不会像我们这里的示例一样简单。使用简单工厂模式,将生成对象的任务交给工厂,客户端只需要“消费”对象。

当需要扩展产品的种类时,我们只需要找到产品类的文件,添加所需的具体产品类,然后在工厂类中添加相应的“生成对象”的代码,最后在客户端中添加“消费对象的代码”,这样就完成了原本很麻烦的扩展任务。

简单工厂模式是不完全遵守“开闭原则”的模式,当有新的具体产品类时就需要修改工厂类中的生成对象的方法。而多方法的简单工厂模式又改善了这种缺点,不同的对象有不同的生成方法,将原本需要在生成对象的方法中进行生成何种对象的判断交给客户端来完成。

工厂模式的好处可以参考这篇博客《设计模式之Factory工厂模式的好处》

(2)简单工厂模式只能用于创建对象吗?

答:其实简单工厂模式可以灵活应用,参考这篇博客《C++工作笔记-简单工厂模式基础》

 

猜你喜欢

转载自blog.csdn.net/gaggagaasd/article/details/107623949
今日推荐