一、使用场景
首先,作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过new就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。
其次,工厂模式是一种典型的解耦模式,迪米特法则在工厂模式中表现的尤为明显。假如调用者自己组装产品需要增加依赖关系时,可以考虑使用工厂模式。将会大大降低对象之间的耦合度。
再次,由于工厂模式是依靠抽象架构的,它把实例化产品的任务交由实现类完成,扩展性比较好。也就是说,当需要系统有比较好的扩展性时,可以考虑工厂模式,不同的产品用不同的实现工厂来组装。
Q:什么是迪米特法则?
A:迪米特法则又叫做最少知道原则,就是说一个对象应当对其它对象有尽可能少的了解,不要和陌生人说话。
强调只和朋友说话,不和陌生人说话。这里的朋友指的是:出现在成员变量,方法输入,输出参数中的类称为成员朋友类,而出现在方法体内部的类不属于朋友类。
迪米特法则初衷在于降低类之间的耦合。由于每个类尽量减少对其它类的依赖,因此。很容易使得系统的功能模块独立,相互之间不存在(或很少有)依赖关系。
Q:复杂对象和简单对象分别是什么?
A:
二、定义
主要是三块:简单工厂类部分、实现类基类部分、实现类具体实现部分,其中实现类基类是稳定的,实现类子类可能需要实时增加类,简单工厂类因为实现的子类增加,内部会增加处理流程这会违反迪米特法则。
下面给出一个实例:调用各种运算符运算。
三、代码
1.运算类基类
class Operation{
public:
virtual double getResult(double numberA, double numberB) = 0;
}
2.运算类实现类
class Add :public Operation{
public:
double getResult(double numberA, double numberB){
return numberA + numberB;
}
}
class Sub :public Operation{
public:
double getResult(double numberA, double numberB){
return numberA - numberB;
}
}
class Mul :public Operation{
public:
double getResult(double numberA, double numberB){
return numberA * numberB;
}
}
class Div :public Operation{
public:
double getResult(double numberA, double numberB){
try{
if(numberB == 0){
cout << "除数不能=0" << endl;
throw -1;
}
}
return numberA / numberB;
}
}
3.简单工厂类
class EasyFactory{
public:
static Operation createOperation(string name){
Operation operationObj = null;
switch(name){
case "+":
operationObj = new Add();
break;
case "-":
operationObj = new Sub();
break;
case "*":
operationObj = new Mul();
break;
case "/":
operationObj = new Div();
break;
}
return operationObj;
}
}
4.客户端代码
int main(){
Operation add = EasyFactory.CreateOperation("+");
Operation sub = EasyFactory.CreateOperation("-");
Operation mul = EasyFactory.CreateOperation("*");
Operation div = EasyFactory.CreateOperation("/");
cout << add.getRsult(1,1) << endl;
cout << sub.getRsult(1,1) << endl;
cout << mul.getRsult(1,1) << endl;
cout << div.getRsult(1,1) << endl;
return 0;
}
四、优点
可以对创建的对象进行一些 “加工” ,而且客户端并不知道,因为工厂隐藏了这些细节。如果,没有工厂的话,就得自己在客户端上写这些代码,这就好比本来可以在工厂里生产的东西,拿来自己手工制作,不仅麻烦以后还不好维护。