摘要说明:本代码只是学习使用,不用于任何其它途径,使用请说明出处。
本章解释什么是简单工厂模式,为后面的工厂模式做铺垫,值得注意的是:简单工厂模式—>不属于<—-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、客户端只知道传入工厂类的参数,对于如何创建对象不关心。
最后我还有还有一句话要说,那有没有解决这种尴尬情况的设计模式,答案是肯定有的。
请参考我的博客工厂方法模式
请打死都要记住:简单工厂模式 +“开闭原则” = 工厂方法模式