目录
1. 设计原则
1.1 单一职责
一个类只负责一项职责
- 问题由来:类T负责两个不同的职责:P1、P2。当P1需求发生变化时,需要修改T类,可能导致P2发生故障
- 解决方案:将P1、P2放在两个类:T1、T2
1.2 里氏替换
所有引用基类的地方都必须能透明地使用其子类的对象,子类可扩展父类的功能,但不能修改父类原有功能
- 问题由来:功能P1由类A完成,将P1扩展为P,P由原功能P1和新功能P2组成。新功能P由A的子类B来完成,B在完成P2的同时,可能使P1发生故障(重写了A的方法,导致调用走了B的方法而结果不一致)
- 解决方案:使用继承时,遵循里氏替换原则,尽量不要重写或重载父类方法
1.3 依赖倒置
高层模块不依赖低层模块,二者都依赖其抽象;细节应该依赖抽象
- 问题由来:类A直接依赖类B,如果类A改为依赖类C,则必须修改类代码,可能给程序带来风险
- 解决方案:类B和类C实现接口K,类A依赖接口K,依赖更改时,不需要修改类A代码
1.4 接口隔离
客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上
- 问题由来:接口I包含1、2、3三个方法,类B只需要对外提供方法1,但是必须实现方法2、3(空实现)
- 解决方案:将接口K拆分为独立的几个接口K1和K2,K1中只有方法1,类B只需要实现接口K1即可
1.5 迪米特原则
一个对象应该对其他对象保持最少的了解
- 问题由来:两个类之间的耦合度越大,当一个类发生变化,对另一个类的影响越大
- 解决方案:降低类之间的耦合
1.6 开闭原则
对扩展开放,对修改关闭
- 问题由来:软件需要变化时对代码的修改可能导致旧代码运行错误
- 解决方案:软件需要变化时,尽量通过扩展软件的功能,避免直接修改旧的代码
2. 设计模式
2.1 创建型
- 简单工厂:模式最简单
- 工厂模式:在简单工厂模式的基础上增加了选择工厂的维度,需要第一步选择合适的工厂
- 抽象工厂模式:有产品族的概念,如果各个产品是存在兼容性问题的,就要用抽象工厂模式
- 单例模式:为了保证全局使用的是同一对象,一方面是安全性考虑,一方面是为了节省资源
- 建造者模式:专门对付属性很多的那种类,为了让代码更优美
- 原型模式:了解 Object 类中的 clone() 方法相关的知识即可
2.2 结构型
- 代理模式:方法的增强
- 装饰者模式:类的增强
- 适配器模式:基于旧类得到需要的新类
- 桥接模式:抽象化与实现化的解耦
- 门面模式:化繁为简,供客户使用
- 组合模式:针对具有层次结构的数据
- 享元模式:对象缓存,避免重复创建
2.3 行为型
- 备忘录模式:状态保存,一键恢复
- 观察者模式:修改目标的数据,触发相应通知,联动调用观察者的方法
- 状态模式:根据状态分离和选择对应的行为
- 策略模式:分离算法,选择实现,算法可任意替换
- 模板方法模式:父类固定算法框架,子类父子框架内部实现
- 访问者模式:为可能扩展的对象预留回路,通过回调的方式进行功能扩展,避免对对象的修改
- 中介者模式:将多个对象之间的交互统一封装
- 迭代器模式:统一访问聚合元素的方法
- 解释器模式:分离实现,解释执行
- 命令模式:将请求封装成对象
- 责任链模式:分离职责,动态组合
3. UML
3.1 类图
类名 | 符合规范的名字 |
属性 | 可见性 属性名:类型名=初值 仅在类内部使用,无get/set方法,称为Attribute,如:nickname 提供了get/set方法,称为Property,如:age、name |
操作 | 可见性 操作名(参数列表):返回值类型 |
- 可见性:
-
- +:public
- -:private
- #:protected
- 无符号表示默认可见性
- 静态属性(name)或方法(run)下面添加一条下划线
- 抽象类或接口类名及操作的定义使用斜体
3.2 关系
在UML2.0中,类图描述的关系包括:关联、泛华(继承)、依赖、实现、使用、流
关系 | 功能 | 表达形式 |
关联 | 类实例之间的连接 | |
泛化 | 概括描述和具体种类间的关系,适用于继承 | |
依赖 | 两个模型元素之间的关系 | |
实现 | 抽象说明和具体实现间的关系,如实现接口 | |
使用 | 一个元素需要使用其他元素功能的关系 | |
流 | 在相继时间内一个对象的两种形式的关系 | |