简单工厂模式
创建型模式关注对象的创建过程,在软件开发中应用非常广泛。创建型模式描述如何将对象的创建和使用分离,让用户在使用对象过程中无须关心对象的创建细节,从而降低系统耦合度,并且让系统易于修改和扩展。
简单工厂模式是最简单的设计模式之一,但应用也十分频繁,同时也是其余创建模式的基础,因此有必要先学习简单工厂模式。
简单工厂模式基本实现流程
由上述例子,可以很容易总结出简单工厂的实现流程:
- 设计一个抽象产品类,它包含一些公共方法的实现;
- 从抽象产品类中派生出多个具体产品类,如篮球类、足球类、排球类,具体产品类中实现具体产品生产的相关代码;
- 设计一个工厂类,工厂类中提供一个生产各种产品的工厂方法,该方法根据传入参数(产品名称)创建不同的具体产品类对象;
- 客户只需调用工厂类的工厂方法,并传入具体产品参数,即可得到一个具体产品对象。
如上图所示,客户向工厂提出自己的需求,工厂根据客户的需求生产出对应的产品,客户并不需要了解产品具体生产的过程。
如上,可以很容易得出简单工厂模式的实现过程:
- 设计一个抽象产品类,它包含一些公共方法的实现;
- 从抽象产品类中派生出多个具体产品类,如篮球类、足球类、排球类,具体产品类中实现具体产品生产的相关代码;
- 设计一个工厂类,工厂类中提供一个生产各种产品的工厂方法,该方法根据传入参数(产品名称)创建不同的具体产品类对象;
- 客户只需调用工厂类的工厂方法,并传入具体产品参数,即可得到一个具体产品对象。
从简单工厂模式的定义和例子可以看出,在简单工厂模式中,大体上有3个角色:
- 工厂(Factory):根据客户提供的具体产品类的参数,创建具体产品实例;
- 抽象产品(AbstractProduct):具体产品类的基类,包含创建产品的公共方法;
- 具体产品(ConcreteProduct):抽象产品的派生类,包含具体产品特有的实现方法,是简单工厂模式的创建目标。
简单工厂模式UML类图如下:
上面上个例子:
simplefactory.h
#include <iostream>
#include <string.h>
using namespace std;
//抽象产品类AbstractProduct
class AbstractSportProduct
{
public:
AbstractSportProduct()
{
}
//抽象方法:
void printName(){
};
void play(){
};
};
//具体产品类Basketball
class Basketball : public AbstractSportProduct
{
public:
Basketball()
{
printName();
play();
}
//具体实现方法
void printName()
{
cout << "Get Basketball\n";
}
void play()
{
cout << "Play Basketball\n";
}
};
//具体产品类Football
class Football : public AbstractSportProduct
{
public:
Football()
{
printName();
play();
}
//具体实现方法
void printName()
{
cout << "Get Football\n";
}
void play()
{
cout << "Play Football\n";
}
};
//具体产品类Volleyball
class Volleyball : public AbstractSportProduct
{
public:
Volleyball()
{
printName();
play();
}
//具体实现方法
void printName()
{
cout << "Get Volleyball\n";
}
void play()
{
cout << "Play Volleyball\n";
}
};
class Factory
{
public:
AbstractSportProduct *getSportProduct(string productName)
{
AbstractSportProduct *pro = NULL;
if (productName == "Basketball")
{
pro = new Basketball();
}
else if (productName == "Football")
{
pro = new Football();
}
else if (productName == "Volleyball")
{
pro = new Volleyball();
}
return pro;
}
};
simplefactory.cc
#include <iostream>
#include "simplefactory.h"
using namespace std;
int main()
{
cout << "简单工厂模式\n";
//定义工厂类对象
Factory *fac = new Factory();
AbstractSportProduct *product = NULL;
product = fac->getSportProduct("Basketball");
if (product)
{
delete product;
}
product = fac->getSportProduct("Football");
if (product)
{
delete product;
}
product = fac->getSportProduct("Volleyball");
if (product)
{
delete product;
}
delete fac;
return 0;
}
编译后,运行输出:
简单工厂模式
Get Basketball
Play Basketball
Get Football
Play Football
Get Volleyball
Play Volleyball
简单工厂模式总结
简单工厂模式的优点在于:
- 工厂类提供创建具体产品的方法,并包含一定判断逻辑,客户不必参与产品的创建过程;
- 客户只需要知道对应产品的参数即可,参数一般简单好记,如数字、字符或者字符串等。
当然,简单工厂模式存在明显的不足。假设有一天Jungle想玩棒球了,通常都会觉得很简单,再从抽象产品类派生出一个Baseball类,并在工厂类的getSportProduct方法中增加“productName == "Baseball”的条件分支即可。
的确如此,但是这明显违背了开闭原则(对扩展开放,对修改关闭),即在扩展功能时修改了既有的代码。另一方面,简单工厂模式所有的判断逻辑都在工厂类中实现,一旦工厂类设计故障,则整个系统都受之影响!