C++简单工厂模式

来源:互联网 发布:反演变换知乎 编辑:程序博客网 时间:2024/06/14 11:28

摘要说明:本代码只是学习使用,不用于任何其它途径,使用请说明出处。

本章解释什么是简单工厂模式,为后面的工厂模式做铺垫,值得注意的是:简单工厂模式—>不属于<—-GoF的23种设计模式

废话不多说,直接上问题代码,如下:

#include "iostream"using namespace std;class Fruit{public:    //构造函数//    Fruit(string name)    {        this->m_Sname = name;        if ("apple" == this->m_Sname)        {            //apple        }        else if ("pear" == this->m_Sname)        {            //pear        }        else if ("banana"==this->m_Sname)        {             //banana        }    }    void getName(){        if (this->m_Sname == "apple")        {            cout << "apple" << endl;        }        else if (this->m_Sname == "pear")        {            cout << "pear" << endl;        }        else if (this->m_Sname == "banana")        {            cout << "banana" << endl;        }    }private:    string m_Sname;};int main(){    Fruit apple("apple");    Fruit pear("pear");    Fruit banana("banana");    apple.getName();    pear.getName();    banana.getName();    system("pause");    return 0;}

OK,到这里很多的新手应该就是这样写的,但是,新手不会发现这样写的话以后会存在以下问题。
1、在Fruit类中包含很多“if…else…”代码块,整个类的代码相当冗长,代码越长,阅读难度、维护难度和测试难度也越大;而且大量条件语句的存在还将影响系统的性能,程序在执行过程中需要做大量的条件判断;

2、Fruit类的职责过重,它负责初始化和显示所有的水果对象,将各种水果对象的初始化代码和显示代码集中在一个类中实现,违反了“单一职责原则”,不利于类的重用和维护;

3、当需要增加新类型的水果时,必须修改Fruit类的源代码,违反了“开闭原则”。

so,既然有了问题,那么该如何去解决这个问题,请仔细看以下问题。

1)啥子是工厂(Factory)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象;
2)啥子是抽象产品(AbstractProduct)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口;
3)啥子又是具体产品(Concrete Product)角色:简单工厂模式所创建的具体实例对象。

如图所示:
简单工厂模型

哇,看了这些图完全搞不懂,很胖胖啊,那就接下来继续看,估计还是看不懂。

来一张简单易懂的图片,如下图:
简单工厂模式案例图实例

实现代码如下:

/*******************************************简单工厂模式**************************//////////////////////////////////////更改代码/////////////////////////////////////*定义一个水果抽象类,供具体水果实现、工厂使用*/class Fruit{public:    virtual void getName()=0;};class Apple :public Fruit{public:     virtual void getName()    {        cout << "Apple" << endl;    }};class Pear :public Fruit{public:    virtual void getName()    {        cout << "Pear" << endl;    }};/*    添加一个香蕉,只需要创建一个香蕉类实现抽象水果类即可*/class Banana :public Fruit{public:    virtual void getName()    {        cout << "Banana" << endl;    }};class Factory{   public:    Fruit * creatFruit(string name){        if ("Apple"==name)        {            return new Apple;        }        else if ("Pear"==name)        {            return new Pear;        }        /*问题来了,当我们创建香蕉类的时候就会在此工厂类中增加代码,Factory会变得越来越大,不符合开闭原则*/        else if ("Banana"==name)        {            return new Banana;        }    }};int main(){    Factory *factory = new Factory;    Fruit *fruit = NULL;    /*        使用工厂类进行创建一个水果类,返回的是抽象类指针        这样做的一个好处是发生了多态        此时抽象类指针指向了具体的子类,调用抽象方法就会调用子类实现的方法        注意:抽象类指针指向了具体的子类 == 父类指针指向子类对象    */    fruit = factory->creatFruit("Apple");    fruit->getName();    delete fruit;    fruit = NULL;    fruit = factory->creatFruit("Pear");    fruit->getName();    delete fruit;    fruit = NULL;    fruit = factory->creatFruit("Banana");    fruit->getName();    delete fruit;    fruit = NULL;    system("pause");    return 0;}

OK,到这里如果你的C++技术不是很薄弱,讲道理看得懂这些的,接下来我们就说说这个简单工厂模式的优缺点。

优点:            1、实现了对对象的创建和使用分离;            2、不需要再去记住具体的类名,只需要记住参数即可,减少开发人员的大脑磁盘。
缺点:            1、对工厂类的职责过分加重,一旦工厂跑路了,整个系统全部就GG了;            2、会增加系统类的个数,系统的复杂度和人员的理解代码度增加,看的你五花六门的;            3、违反了“开闭原则”,即添加新的产品的时候,需要在工厂类中去修改逻辑,系统工厂会越来越复杂,到最后维护成本过大,推翻所有重新设计。

最后,感觉这个东西好像貌似可能也许大概没有什么用,no no no ,属于简单工厂模式的场景有如下(只做参考,非权威):
1、工厂类负责创建的对象比较少,由于创建的对象少,不会整么造成工厂方法中的业务逻辑太过于复杂;
2、客户端只知道传入工厂类的参数,对于如何创建对象不关心。

最后我还有还有一句话要说,那有没有解决这种尴尬情况的设计模式,答案是肯定有的。

请参考我的博客工厂方法模式

请打死都要记住:简单工厂模式 +“开闭原则” = 工厂方法模式

原创粉丝点击