开了一个新的专栏,把设计模式再重新捡起来的,包括好多没学过的设计模式,都过一遍,巩固已知的,学习未知的!
先说说设计模式的好处吧
就是发挥了面向对象编程的三大特性:封装、继承和多态,把程序耦合性降低,使用设计模式让程序更加的灵活、已扩展修改和复用。
从最最最最基本的简单工厂模式开始吧
工厂模式:就是要啥生产啥,生产零件的地方。零件又相当于一个个对象,其实就是批量生产对象
比如要实现一个加减乘除四则运算,平常拿到这么个需求就想着,这个简单,不就一个Switch语句就搞定了吗?
啊那在main里面写个Switch,case中做加减乘除操作,然后返回结果(经常就这样了)
- #include
- using namespace std;
-
- int main(int argv[]) {
- double numA = 1.0;
- double numB = 4.0;
-
- char opertorChar;
- cin>>opertorChar;
- double result = 0;
- switch (opertorChar)
- {
- case '+':
- result = numA + numB;
- break;
- case '-':
- result = numA - numB;
- break;
- case '*':
- result = numA * numB;
- break;
- case '/':
- result = numA / numB;
- break;
- default:
- break;
- }
-
- cout << result << endl;
- }
据书上说这就是典型的面向过程编程,如果再加一个求平方、取余,就又需要去更改Switch语句,要是一不小心改了原有代码,那不是惨了,而且因为新增是在原Switch进行修改,原来的逻辑又得测试一遍,增加成本,还不好维护
通过面向对象来做,就会方便很多,首先抽象一个运算类出来,加减乘除就继承这个运算类
- #include
- using namespace std;
-
- // 运算类基类
- class Operation {
- public:
- virtual void showResult(double numA, double numB) {}
- };
-
- // 加减运算子类
- class OperateAdd : public Operation {
- public:
- void showResult(double numA, double numB) {
- cout << "add result: " << numA + numB << endl;
- }
- };
-
- class OperateSub : public Operation {
- public:
- void showResult(double numA, double numB) {
- cout << "sub result: " << numA - numB << endl;
- }
- };
-
- class OperateRide : public Operation {
- public:
- void showResult(double numA, double numB) {
- cout << "sub result: " << numA * numB << endl;
- }
- };
-
- class OperateDivide : public Operation {
- public:
- void showResult(double numA, double numB) {
- cout << "sub result: " << numA / numB << endl;
- }
- };
这就解决了第一个问题,再加一堆的运算,我就再加新的类就好了,也不用去修改原有的类
但是在mian里面岂不是还要写switch,根据类型实例化不同的运算子类,那不还是有问题吗?这不,简单工厂模式就能解决这个问题
定义一个运算的工厂类,用一个静态方法来生产运算类的对象
- //定义简单工厂类
- class SimpleFactory {
- public:
- static Operation* CreateOperator(char opType) {
- Operation* op;
- switch (opType)
- {
- case '+':
- op = new OperateAdd();
- break;
- case '-':
- op = new OperateSub();
- break;
- case '*':
- op = new OperateSub();
- break;
- case '/':
- op = new OperateDivide();
- break;
- default:
- break;
- }
-
- return op;
- }
- };
在mian里面,就只需要调用这一个方法获取对应的运算对象即可
- int main(int argv[]) {
- Operation* op = SimpleFactory::CreateOperator('+');
- op->showResult(2.0, 5.0);
- }
这样就变成了维护工厂类了,而且main里面也把逻辑和显示分离开了,这个运算类和工厂类以后不是放哪都能用吗,像原来都写在main中,其他地方要用,又得CV过去,一改全改,折磨人简直。
这里面就用到了面向对象的三大特性了
当然不是所有的设计模式都完美无缺的,需求的变更都是要成本的,但是成本高低还是有区别的