简单工厂模式最大的优点就是在于工厂类中,包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了其他不必要的麻烦。
只需要把’+'给工厂,就可以自动出相应的实例,计算结果即可。但是,简单工厂模式中,我需要添加功能,在抽象中,的确是只需要增加一个纯虚函数,再加一个实现即可,我觉得不会影响开闭原则啊。
后面发现自己too young了,我需要在switch里面修改代码啊,不仅拓展了开放,还对修改也开放了,违背了开闭原则。
通过今天的工厂方法模式学习,又加深了面向对象设计的了解,越来越发现,这样写代码实在太舒服了。
class Operation//一个运算类,和一个获取结果的虚函数
{
public:
virtual double GetResult(double a, double b)//父类虚函数,用于获取计算结果
{
double result = 0;
return result;
}
};
对这个运算类,可以衍生多个运算方法的儿子。
class Add : public Operation//加法类继承父类,重写虚函数
{
public:
//功能实现
virtual double GetResult(double a, double b)
{//具体功能实现
return a + b;
}
};
加减乘除。
class Sub : public Operation
{
public:
virtual double GetResult(double a, double b)
{
return a - b;
}
};
class Mul : public Operation
{
public:
virtual double GetResult(double a, double b)
{
return a * b;
}
};
class Div : public Operation
{
public:
virtual double GetResult(double a, double b)
{
if (b == 0)
{
return a / (b + 1);
}
else
return a / b;
}
};
下面我要建造一个抽象工厂了,每个子工厂负责生成一个单独的算法类,需要什么,就出什么工厂。
class Factory//抽象的工厂,不能实例化
{
public:
virtual Operation* CreateOperation() = 0;//抽象工厂
};
下面一共是4个工厂,分别生产加减乘除。
class AddFactory : public Factory
{
public:
Operation* CreateOperation()
{
return new Add();
}
};
class SubFactory : public Factory
{
public:
Operation* CreateOperation()
{
return new Sub();
}
};
class MulFactory : public Factory
{
public:
Operation* CreateOperation()
{
return new Mul();
}
};
class DivFactory : public Factory
{
public:
Operation* CreateOperation()
{
return new Div();
}
};
下面是客户端代码
int main()
{
Factory *F = new AddFactory();//我需要加法
Operation *o = F->CreateOperation();//让加法工厂生产
double a = o->GetResult(1, 2);
cout << a << endl;
getchar();
}
工厂方法模块实现时,客户端需要决定实例化哪个工厂来实现运算类,选择判断的问题还是存在,只是把内部的逻辑判断转移到客户端罢了。
只是,需要增加功能的时候,本来是修改工厂类,现在只是增加一个运算类和修改客户端。
优点是:符合了开闭原则,可拓展性增强
缺点是:增加了客户端的负担,代码量变大