前言
学习设计模式,需要了解面向对象思想。利用面向对象思想的特性,能够帮助我们设计出优秀的程序。
面向过程思想
特点
- 关注点:正在发生的过程
- 事情的发生按照一定的“逻辑时间顺序”
- 符合多数人思考、计算机处理问题的逻辑
示例(C++语言描述)
#include <iostream>
using namespace std;
int main()
{
//定义并初始化变量
int num1 = 1; //操作数1
char oper = '+'; //计算符
int num2 = 2; //操作数2
int result = 0; //计算结果
//判定并计算
switch (oper)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
default:
break;
}
cout << result << endl; //输出计算结果
return 0;
}
程序先定义并初始化变量,然后进行判断计算,最后输出结果。程序的执行“从上至下”(按照语句顺序),“从过去到未来”(按照时间顺序)经历一定的过程。
缺点
- 维护性差
- 复用性差
- 扩展性差
- 灵活性差
优秀程序设计的四个特性
在实际业务、服务开发中,需求变化,程序就要修改。优秀程序设计旨在用更短的时间、变动更少的代码、按一定设计步骤有序无差错地完成任务。
- 维护性:只修改相关代码/功能,而不影响其他代码/功能
- 复用性:代码/功能可重复使用
- 扩展性:能在原有代码/功能基础上,增添新的代码/功能
- 灵活性:代码/功能适用于多种场景
面向对象思想
关注点:正在受影响的对象
三大特性:封装,继承,多态
封装
目的
- 拆分逻辑
- 降低耦合度
- 隐藏实现细节
- …
示例(C++语言描述)
#include <iostream>
using namespace std;
//计算类
class Operation
{
public:
int num1; //操作数1
char oper; //计算符
int num2; //操作数2
int result; //计算结果
//计算方式
void calculate()
{
switch (oper)
{
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
default:
break;
}
}
};
int main()
{
//创建并初始化计算类的对象
Operation operation;
operation.num1 = 1;
operation.oper = '+';
operation.num2 = 2;
operation.calculate(); //计算
cout << operation.result << endl; //输出计算结果
return 0;
}
程序定义了一个计算类,将”操作数、操作符、计算结果和计算方式”逻辑相似且共同实现一种功能的“实体”封装;在主函数中将计算的业务逻辑和输出显示的界面的代码逻辑拆分,修改代码可选择只修改其中一部分而不影响另一部分,耦合度降低;对主函数而言,计算类的实现细节是隐藏的,主函数只需知道如何调用,可以将计算类复用在其他位置。
继承和多态
目的
- 拆分逻辑
- 降低耦合度
- …
当需要修改计算类时,仍然存在耦合度高的问题。例如想为其增添“乘法计算”功能,则需在“calculate()”函数的“switch”语句中添加代码,可能会错误修改“加法、减法计算”功能的代码。
示例(C++语言描述)
#include <iostream>
using namespace std;
//计算类
class Operation
{
public:
int num1; //操作数1
char oper; //计算符
int num2; //操作数2
int result; //计算结果
virtual void calculate() = 0; //纯虚函数
};
//计算加法类
class Operation_add : public Operation //继承
{
void calculate() //重载 多态
{
result = num1 + num2;
}
};
//计算减法类
class Operation_sub : public Operation
{
void calculate()
{
result = num1 - num2;
}
};
//计算乘法类
class Operation_mul : public Operation
{
void calculate()
{
result = num1 * num2;
}
};
/**
* 程序设计思路:依据给定的计算符,创建计算类相应的子类对象,调用子类的方法计算
* 使用简单工厂模式
*/
//计算工厂类
class Operation_factory
{
public:
static Operation *create_operation(char oper) //静态函数
{
Operation *operation = NULL; //指向计算类的指针
//依据给定的计算符,创建计算类相应的子类
switch (oper)
{
case '+':
operation = new Operation_add();
break;
case '-':
operation = new Operation_sub();
break;
case '*':
operation = new Operation_mul();
break;
default:
break;
}
return operation; //返回相应的计算子类对象
}
};
int main()
{
//依据给定的计算符,创建计算类相应的子类对象并初始化
Operation *operation = Operation_factory::create_operation('+');
//静态函数属于类而不是对象,由类直接调用
operation->num1 = 1;
operation->num2 = 2;
operation->calculate(); //计算
cout << operation->result << endl; //输出计算结果
return 0;
}
通过继承,将“计算”的各个“子功能”逻辑拆分,每个功能单独成一“类”,耦合度降低;通过多态,将函数重载以实现不同的计算。当再想增加一个“除法计算”功能时,只需增加一个计算除法子类,并在计算工厂类的“switch”语句中增加一个创建计算除法子类对象的分支,而不会“触碰”/误修改到“加、减和乘法计算”功能的代码,提高了程序的维护性。
总结
- 面向过程的关注点:正在发生的过程
- 优秀程序设计的四大特性:维护性,复用性,扩展性,灵活性
- 面向对象的关注点:正在受影响的对象
- 三大特性:封装,继承,多态
作者的话
- 文章内容基于读者有一定程序设计基础,了解面向过程、对象思想等一定知识,主要目的是对知识的串讲、延拓,详细概念理解请参阅其他资料
- 文章内容示例简单,思想优越性的体现可能不理想。当拓展到大型业务、服务和程序时,务须具备高效的设计思想、使用良好的设计模式编程
- 文章在描述时有疑惑的地方,请留言,必会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获
参考资料
《大话设计模式》作者:程杰