简单工厂模式并不属于GoF的23种设计模式。
那么为什么我要用工厂模式呢?请看下面的一段程序。
#include<iostream>
using namespace std;
//水果类
class Fruit
{
public:
Fruit(string name)
{
m_name = name;
}
void showFruitName()
{
if (m_name.compare("apple") == 0)
{
cout << "我是苹果" << endl;
}
else if (m_name.compare("banana") == 0)
{
cout << "我是香蕉" << endl;
}
else if (m_name.compare("pear") == 0)
{
cout << "我是鸭梨" << endl;
}
}
private:
string m_name;
};
int main()
{
Fruit* apple = new Fruit("apple");
Fruit* banana = new Fruit("banana");
Fruit* pear = new Fruit("pear");
apple->showFruitName();
banana->showFruitName();
pear->showFruitName();
system("pause");
return EXIT_SUCCESS;
}
不难看出,Fruit类是一个“巨大的”类,在该类的设计中存在如下几个问题:
(1) 在Fruit类中包含很多“if…else…”代码块,整个类的代码相当冗长,代码越长,阅读难度、维护难度和测试难度也越大;而且大量条件语句的存在还将影响系统的性能,程序在执行过程中需要做大量的条件判断。
(2) Fruit类的职责过重,它负责初始化和显示所有的水果对象,将各种水果对象的初始化代码和显示代码集中在一个类中实现,违反了“单一职责原则”,不利于类的重用和维护;
(3) 当需要增加新类型的水果时,必须修改Fruit类的源代码,违反了“开闭原则”。
模式中的角色和职责
工厂(Factory)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
抽象产品(AbstractProduct)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色:简单工厂模式所创建的具体实例对象。
简单工厂模式案例
#include<iostream>
#include<string>
using namespace std;
//抽象水果
class Fruit
{
public:
virtual void shoName() = 0;
};
//苹果类
class Apple : public Fruit
{
public:
virtual void shoName()
{
cout << "我是苹果" << endl;
}
};
//香蕉类
class Banana : public Fruit
{
public:
virtual void shoName()
{
cout << "我是香蕉" << endl;
}
};
//鸭梨类
class Pear : public Fruit
{
public:
virtual void shoName()
{
cout << "我是鸭梨" << endl;
}
};
//水果工厂
class FruitFactory
{
public:
static Fruit* CreateFruit(string name)
{
if (name.compare("apple") == 0)
{
return new Apple;
}
else if (name.compare("banana") == 0)
{
return new Banana;
}
else if (name.compare("pear") == 0)
{
return new Pear;
}
}
};
//测试
void test01()
{
Fruit* fruit = NULL;
fruit = FruitFactory::CreateFruit("apple"); //工厂生产苹果
fruit->shoName();
delete fruit;
fruit = FruitFactory::CreateFruit("banana"); //工厂生产香蕉
fruit->shoName();
delete fruit;
fruit = FruitFactory::CreateFruit("pear"); //工厂生产鸭梨
fruit->shoName();
delete fruit;
}
int main() {
test01();
system("pause");
return EXIT_SUCCESS;
}
简单工厂模式的优缺点
优点:
(1)实现了对象创建和使用的分离。
(2)不需要记住具体类名,记住参数即可,减少使用者记忆量。
缺点:
(1)对工厂类职责过重,一旦不能工作,系统受到影响。
(2)增加系统中类的个数,复杂度和理解度增加。
(3)违反“开闭原则”,添加新产品需要修改工厂逻辑,工厂越来越复杂。
适用场景
- 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。