为什么需要面向对象设计
从需求开始谈起
- 需求总是不完整的,错误的,容易让人产生误解
- 需求一直在变化
- 用户对需求的看法,可能在与开发人员讨论以及看到软件新的可能性后发生变化
- 随着对问题的熟悉, 开发人员对问题领域的看法也会变化
例子
假设你在一个会议上担当讲师, 听课的人在课后还要去听其他课程, 但他们不知道下一堂课的听课地点,
你的责任就是, 确保大家都知道下一节课去哪儿上。
结构化的分析方法
- 获取听课人的名单
- 对于名单上的每个人 , 做如下事情
- 在教室的后面贴一张地图, 标出每个教室的位置和路线
- 告诉大家: “下课后大家自己去看后面的地图, 自己找下一节课的位置”
到底谁来负责?
责任的转移:
第一种方法: 直接给每个人提供指示, 责任全在老师自己身上
第二种方法:只给出通用的指示(调用接口), 让每个人自己去完成任务 (面向对象的思路), 责任在各个学生身上
让责任划分到合适的对象当中!面向对象设计的好处
老师只需要对Student发出一个“笼统”的指令:gotoNextClassroom() 即可, 不用关心实现细节
思考: 假设出现了需求变更, 你讲的课有研究生作为助教, 它们需要把本节课的反馈收集一下,先交到会议办公室,然后再去下一个教室。对于结构化设计和OOD怎么应对?应对变更
- 对于结构化设计, 不得不对控制程序进行修改, 加上if else 判断以区分研究生和普通学生, 给研究生以特殊指令 – 修改控制程序,容易产生bug
对于OOD , 根本不区分研究生和普通学生, 只是对Student这个抽象概念说: gotoNextClassRoom()
for (Student student : students){
// Student 可能是普通学生,也可能是研究生助教
student.gotoNextClassRoom();
}
总结
职责转移
- 把职责划分到合适的类中去
- 把细节封装起来
只对接口进行操作
发现变化并且封装变化
- 找出可变之处, 把它独立出来,不要和那些不需要变化的代码混在一起。
- 一个抽象的过程。
- 针对接口编程而不是针对实现编程
-
面向对象设计原则
面向对象基本五大设计原则有:
单一职责原则 (SRP,Single Responsibility Principle )
- 开闭原则 (OCP,Open Closed Principle)
- 里氏替换原则 (LSP,Liskov Substitution Principle)
- 接口隔离原则 (ISP,Interface Segregation Principle)
- 依赖倒置原则 (DIP,Dependence Inversion Principle)
把这五个原则的首字母联合起来就是 SOLID (solid,稳定的),其代表的含义就是这五个原则结合使用的好处:建立稳定、灵活、健壮的设计。
另外还有两个设计原则:
- 迪米特法则 (LoD,Law of Demeter)
- 又称最少知识原则(LKP,Least Knowledge Principle)
- 合成复用原则 (Composite Reuse Principle,CRP)