-
Notifications
You must be signed in to change notification settings - Fork 43
面向对象技巧
-
内聚和耦合
- 内聚指一个模块内部元素彼此结合的紧密程度。 是否专注模块的职责,才是内聚性的充要条件
*【内聚的分类】
* 【巧合内聚(Coincidental cohesion)】- 最差。但实际存在,类似“Utils”这样的包 * 【逻辑内聚(Logical cohesion)】 * 【时序内聚】 * 【过程内聚(Procedural cohesion)】 * 【交互内聚(Communicational cohesion)】 * 【顺序内聚(Sequential cohesion)】 * 【功能内聚(Functional cohesion)】
-
耦合(或者称依赖)是程序模块相互之间的依赖程度。
-
【耦合的分类】
-
【无耦合(No coupling)】
-
【消息耦合(Message coupling (low))】
-
【数据耦合(Data coupling)】
-
【数据结构耦合( Data-structured coupling)】
-
【控制耦合(Control coupling)】
-
【外部耦合(External coupling)】
-
【全局耦合(Globaling coupling)】
-
【内容耦合(Content coupling)】- 最差
-
-
高内聚低耦合
- 无论是“低内聚”,还是“高耦合”,其本质都是“不稳定”,不稳定就会带来工作量,带来风险,这当然不是我们希望看到的,所以我们应该做到“高内聚低耦合”。
-
类设计原则-SOLID
-
SRP,single responsibility principle,中文翻译为“单一职责原则”!
-
SRP 可以翻译成“一个类只负责一组相关的事情”
-
用于类的设计
-
-
OCP,Open-Closed Principle,中文翻译为“开闭原则”。
-
完整的 OCP 原则实际上应该这样表述:翻译一下就是:对使用者修改关闭,对提供者扩展开放!
-
是设计的总的指导思想
-
-
LSP,Liskov substitution principle,中文翻译为“里氏替换原则”
-
- 子类必须实现或者继承父类所有的公有函数,否则调用者调用了一个父类中有的函数,而子类中没有,运行时就会出错;
-
- 子类每个函数的输入参数必须和父类一样,否则调用父类的代码不能调用子类;
-
- 子类每个函数的输出(返回值、修改全局变量、插入数据库、发送网络数据等)必须不比父类少,否则基于父类的输出做的处理就没法完成。
-
用于指导类继承的设计
-
-
ISP,Interface Segregation Principle,中文翻译为“接口隔离原则”
-
客户端不应该被强迫去依赖它们并不需要的接口。
-
ISP 原则承认对象需要非内聚的接口,然而 ISP 原则建议客户端不需要知道整个类,只需要知道具有内聚接口的抽象父类即可。
-
例子, 一体机,我们并不会设计一个“一体机”的接口,而是设计 N 个接口。
-
用于指导接口的设计
-
-
DIP,dependency inversion principle,中文翻译为“依赖倒置原则”
-
- 高层模块不应该直接依赖低层模块,两者都应该依赖抽象层;
-
- 抽象不能依赖细节,细节必须依赖抽象;
-
用于指导如何抽象
-
-
-
NOP,No Overdisgn Priciple,不要过度设计原则。
- 过犹不及。 面向对象的初衷虽然是为了拥抱变化,但这个变化也是有一个度的,而不是预测得越长越好,原因很简单:预测越长,预测的结果正确性越低!
-
【定义】
- GoF 在《设计模式》一书中借用了 Christopher Alexander 对设计模式的定义: “模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心”,即:模式是重复发生的问题的解决方案。
-
设计模式只是一把锤子,不是全能的“瑞士军刀”
-
《设计模式》的副标题是:可复用面向对象软件的基础!
-
1)设计模式解决的是“可复用”的设计问题;
-
2)设计模式应用的领域是“面向对象”;
-
-
-
23 个设计模式只是告诉了我们 how,而设计模式之道却可以告诉我们 why 和 where! 得不停的悟道。
-
设计模式之道: 对变化的概念进行封装(encapsulate the concept that varies); Find what varies and encapsulate it, 翻译一下即“找到变化,封装变化”
-
“一个中心,两个基本点”
- “找到变化,封装变化”的设计模式之道,加上 GoF 给出的“基于接口编程,而不是基于实现编程” “优先使用对象组合而不是类继承”两个设计原则,组成了《设计模式》一书中 23 个设计模式的指导思想, 我称之为设计模式的“一个中心,两个基本点”,紧紧抓住这个指导思想,理解起来 23 个设计模式就容易多了。
-
模式详解
-
在实际应用的时候,我们不要一开始就想着要把某个模式塞到某个地方,而是先找到可能变化的地方,再来看具体使用哪个模式可以封装这种变化。
-
DECORATOR 模式
-
FACADE 模式
-
OBSERVER 模式
-
PROTOTYPE 模式
-
其他
-
-
UML,Unified Modeling Language,中文翻译为“统一建模语言”。 目前已经基本上成为了事实上的工业标准。
-
最常见的误解是:掌握 UML,就掌握了设计;设计就是画 UML 图!
-
UML != 设计, just a langue,a tool.
-
UML 最大的作用在于“统一”;都用一样的语言来表述就简单方便了。
-
UML 应用
- 需求分析阶段
用例图
用例图架起了一座从客户需求过渡到软件开发的桥梁
直观的描述系统对外提供的功能
用例之间的关系
1)泛化
2)包含
3)扩展
4)依赖
- 设计阶段
类图
类图主要包含两部分:类定义和类关系
接口
接口可以认为是一个特殊的类,这个类只有抽象方法,没有属性。
类关系图
继承
实现
关联
关联:association,中文还有另外一个翻译:“与 。。。 。。。的交往”,而我认为拿这个翻译来理解“关联”是再合适不过了。
关联不等于关系。 UML 中类的关系有如下几种:继承/实现、依赖关系、组合关系、聚合关系,关联关系。
依赖
依赖是比关联更强的一种关系,一个类“依赖”了另外一个类,就意味着一旦被依赖的类发生改变,则依赖类也必须跟着改变。
方法调用
数据依赖
对象依赖
组合 && 聚合
相比依赖关系,聚合(aggregation)和组合(composition)又是更强的一种关系。依赖关系可以形象的描述为“没有你,我寸步难行”,而聚合和组合则可以形象的描述为“没有你,我将不存在”。
聚合:是一种“has a”的关系,即:某个类包含另外一个类,但并不负责另外类的维护,且两个类的对象生命周期是不一样的,“整体”销毁后,“部分”还能继续存在。
组合:是一种“owns a”的关系,即:某个类包含另外一个类,且还要负责另外类的维护,且两个类的对象生命周期是一样的,“整体”销毁后,“部分”同样被销毁了。
动态图
状态图
状态图主要用于描述一个对象的生命周期内的状态变化。
状态图:关注单个对象或者业务的“状态变化”
活动图
活动图主要用于描述一个工作流程或者计算流程。其关注点是在完成某项工作的过程中,系统中的哪些对象承担了什么样的任务、做了什么处理,以及这些对象之间的先后交互关系。
活动图:关注某个业务或者功能的“实现流程”
交互图
序列图
其关键特征是强调按照“时间顺序”来组织对象的交互
协作图
结构图
组件图
- 部署阶段
部署图
部署图描述的是系统运行时的物理结构,展示了硬件的配置、硬件之间的关系
Just build something.