前言
我们知道,设计模式的终极目标是高内聚,低耦合,好的软件代码必然离不开好的设计。最近在学习设计模式这块的内容,参考的书籍是程杰的《大话设计模式》,这本书对于初学者来说比较友好,易上手,博客里的内容是参考本书以及网络资源整理的。
博客更新基本上是边学边写的过程,写这个专题一是为了作为自己的知识备忘,二是希望能给正在学习设计模式的童鞋一些参考,博客中内容有纰漏或错误之处,还请指出,谢谢。
基本定义
简单工厂模式又称之为静态工厂方法,属于创建型模式。在简单工厂模式中,可以根据传递的参数不同,返回不同类的实例。简单工厂模式定义了一个类,这个类专门用于创建其他类的实例,这些被创建的类都有一个共同的父类。
UML图
简单工厂模式包含以下几类角色:
ProductFactory:工厂角色。专门用于创建产品示例的类,提供CreateProduct方法,可以根据参数类型返回不同类的具体示例。
Product:抽象产品角色,是所有具体产品的父类。
ConcreteProduct:具体产品角色,可存在多个。
简单工厂模式,将具体对象的创建与对象本身的业务分离,降低系统耦合度。当新增产品角色或修改产品角色时,只需要更改或新增具体的类,外部代码无需作改变。
简单工厂模式实例
场景:实现一个功能简单的计算器,输入为num1,num2,op,得到计算结果。如num1=3,num2=4, op='+',则得到结果7。
UML图
代码实现
1. Operation类文件
//Operation类
class Operation {
public:
virtual double GetResult() = 0;
void SetNum(double _num1, double _num2)
{
num1 = _num1;
num2 = _num2;
}
private:
double num1;
double num2;
};
2. OperationAdd类文件
class OperationAdd : public Operation {
public:
double GetResult()
{
return num1 + num;
}
};
3. OperationSub类文件
class OperationSub : public Operation {
public:
double GetResult()
{
return num1 - num;
}
};
4. OperationMul类文件
class OperationMul : public Operation {
public:
double GetResult()
{
return num1 * num;
}
};
5. OperationDiv类文件
class OperationDiv : public Operation {
public:
double GetResult()
{
if (num2 == 0) {
std::cout << "除数不能为0!" << std::endl;
return -1;
}
return num1 / num2;
}
};
6. OperationFactory类文件
class OperationFactory {
public:
Operation CreateOperation(std::string operate)
{
Operation* oper = NULL;
if (oprate == "+") {
oper = new OperationAdd();
} else if (oprate == "-") {
oper = new OperationSub();
} else if (oprate == "*") {
oper = new OperationMul();
} else if (oprate == "/") {
oper = new OperationDiv();
}
return oper;
}
};
7. 客户端测试代码
int main(int argc, char* argv[])
{
Operration operation;
OperationFactory factory;
operation = factory.CreateOperation("+");
operation.SetNum(3, 4);
operation.GetResult();
return 0;
}
优缺点和使用场景
优点:
1. 创建对象不需要单独实例化,而是通过工厂类直接获取实例(实现复用),客户端不需要知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
2. 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性。
缺点:
添加新产品类时,需要同时修改工厂类中生产产品的代码,不符合开闭原则。于是为了通过扩展来实现生产新产品,引入了<工厂方法模式>。
使用场景:
产品类数量较少,且产品类不需要频繁添加的场景。