1.4 面向对象编程
int main(){
double _numberA,_numberB,result;
char operate;
scanf("输入数字A");
scanf("输入数字B");
scanf("输入运算符");
if(operate=='+'){
result = _numberA + _numberB;
}
if(operate=='-'){
result = _numberA - _numberB;
}
...
return 1;
}
碰到问题直觉得用计算机能够理解的逻辑来描述和表达待解决的问题及具体的求解过程,本身没有错,但这样的思维却使得我们的程序只为满足实现当前的需求,程序不容易维护,不容易扩展,更不容易复用。从而达不到高质量代码的要求。
如果要复用上述运算代码,则需要将运算的代码进行复制(Ctrl+C)、粘贴(Ctrl+V),不容易复用。
1.6 面向对象的好处
我们原先(上边)所写的程序,不容易维护,灵活性差,不容易扩展,更谈不上服用,因此面对需求变化,对程序动大手术,几乎重头来过。
学习了面向对象的分析设计编程思想之后,开始考虑通过封装、继承、多态把程序的耦合度降低,开始用设计模式使得程序更加的灵活,容易修改,并且易于服用。
1.7 复制vs复用
当你的代码中重复的代码多到一定程度,维护的时候,可能就是一场灾难。越大的系统,这种方式带来的问题越严重,编程有一原则,就是用尽可能的办法去避免重复。
分一个类出来,让计算(业务)和显示分开。
1.8 业务的封装
让业务的逻辑与界面逻辑分开,让它们的耦合度下降,只有分离开,才可以达到容易维护和扩展。
class Operation{
static double GetResult(double numberA, double numberB, char operate){
double result = 0.0;
switch(operate)
{
case '+':
result = numberA + numberB;
break;
case '-':
result = numberA - numberB;
break;
case '*':
result = numberA * numberB;
break;
case '/':
result = numberA / numberB;
break;
}
return result;
}
};
将业务逻辑代码封装,把业务和界面分离,达到服用效果,其他程序也可复用这个运算类(Operation)了。
这里用到的是封装(业务封装),没有使用到继承和多态,不能很灵活的修改和扩展。
1.9 紧耦合 vs 松耦合
使用1.8的运算类,如果要加一个平方根运算,需要修改GetResult方法添加一个分支,会让加减乘除的运算来参与编译(需要提供加减乘除算法代码),如果不小心改动了原来的代码会得不偿失。所以使用继承和多态,将加减乘除运算分离,修改其中一个不影响另外几个。
class Operation
{
public:
void SetNumberA(double number){
_numberA = number;
}
void SetNumberB(double number){
_numberB = number;
}
double GetNumberA(){
return _numberA;
}
double GetNumberB(){
return _numberB;
}
virtual double GetResult(){
double result = 0;
return result;
}
private:
double _numberA;
double _numberB;
};
class OperationAdd : public Operation{
public:
double GetResult(){
double result = 0;
result = GetNumberA() + GetNumberB();
}
}
1.10 简单工厂模式
使用1.9的运算类,如何让计算器知道我是希望用哪一个算法(如何让应用程序创建对象)?
如何去实例化对象,到底要实例化谁,将来会不会增加实例化的对象,比如增加开跟运算,这是很容易变化的地方,应该考虑用一个单独的类来做这个创造实例的过程,这就是工厂。
//简单运算工厂类
class OperationFactory{
public:
static Operation* CreateOperate(char operate){
Operation* oper = NULL;
switch(operate){
case '+':
oper = new OperationAdd();
break;
case '-':
oper = new OperationSub();
break;
case '*':
oper = new OperationMul();
break;
case '/':
oper = new OperationDiv();
break;
}
return oper;
}
};
//客户端代码
int main(){
Operation* oper = OperationFactory::CreateOperate('+');
oper->SetNumberA(1.0);
oper->SetNumberB(2.0);
double result = oper->GetResult();
return 0;
}
输入参数,通过工厂类实例化出合适的对象,通过运算类的多态,实现了计算结果。
如果有一天我们需要更其中的运算类(例如修改加法运算类),只需要修改OperationAdd就可以了。
如果要增加一种运算类,只需要增加运算类(Operation)相应的子类就可以了。同时修改创建运算类的工厂类,在switch中增加创建新的运算类的分支。