1可复用性
降低成本和开发时间
经过充分 测试,可靠、稳定
标准化,在不同应用中保持一致
白盒复用:源代码可见,可修改和扩展
复制已有代码到正在开发的系统,进行修改
可定制化程度高
对 其修改增加了软件的复杂度,且需要对其内部充分的了解
黑盒复用:源代码不可见,不能修改
只能通过API接口来使用,无法修改代码
简单,清晰
适应性差
2 模块复用
inheritance继承:子类继承父类
delegation委托:一个对象依赖于另一个对象的部分功能
3 库级别复用
形成APIs
Apache
4 系统级别的复用
通过framework复用
开发者根据 framework的规约,填充自己的代码进去,形成完整系统
将framework看作是更大规模的API复用,除了提供可复用的API,还将这 些模块之间的关系都确定下来,形成了整体应用的领域复用
白盒框架,通过代码层面的继承进行框架扩展
黑盒框架,通过实现特定接口/delegation进行 框架扩展
5 可复用的类
- Inheritance and overriding 继承与重写
- Overloading 重载
- Parametric polymorphism and generic programming 参数多态与泛型编程
- Behavioral subtyping and Liskov Substitution Principle (LSP) 行为子类型 与Liskov替换原则
- Composition and delegation 组合与委托
子类型多态:客户端可用统一的方式处理 不同类型的对象
- 子类型可以增加方法,但不可删 子类型需要实现抽象 类型 (接口、抽象类)中所有未实现的方法 子类型中重写的方法
- 必须有相同或子类型的返回值或者符合co-variant的参数 子类型中重写的
- 方法必须使用同样类型的参数或者符合contra-variant的参数(此种情况Java目 前按照重载overload处理)
- 子类型中重写的方法不能抛出额外的异常
6 LSP
- Same or stronger invariants 更强的不变量
- Same or weaker preconditions 更弱的前置条件
- Same or stronger postconditions 更强的后置条件
在强行为子类型化中
- 前置条件不能强化
- 后置条件不能弱化
- 不变量要保持
- 子类型方法参数:逆变
- 子类型方法的返回值:协变
- 异常类型:协变
7 协变
父类型→子类型:越来越具体specific
返回值类型:不变或变得更具体
异常的类型:也是如此
8 逆变
父类型→子类型:越来越具体specific
参数类型:要相反的变化,要不变或越来越抽象
Java中 数组是协变的: 对T[]数组,可以保存类型T及其子类型的数据
9 委托
委托:一个对象请求另一个对象的功能
例子:
如果子类只需要复用父类中的一小部分方法,可以不需 要使用继承,而是通过委派机制来实现
一个类不需要继承另一个类的全部方法,通过委托机制调用部分方法,从而避免继承大量无用的方法
“委托” 发生在object层面,而“继承”发生在class层面
10 CRP设计模式
11 适配器模式
将某个类/接口转换为client期望的其他形式
解决类之间接口不兼容的问题
通过增加一个接口,将已存在 的子类封装起来,client面向接口编程,从而隐藏了具体子类
12 装饰器模式
为对象增加不同侧面的特性
对每一个特性构造子类,通过委派机制增加到对 象上
接口:定义装饰物执行的公共操作
起始对象,在其基础上增加功能(装饰),将通用的方法放 到此对象中
13facade 外观模式
客户 端需要通过一个简化的接口来访问复杂系统内的功能
提供一个统一的接口来取代一系列小接口调用,相当于对复杂 系统做了一个封装,简化客户端使用
便于客户端学习使用,解耦
14 策略模式
有多种不同的算法来实现同一个任务,但需要client根据需要 动态切换算法,而不是写死在代码里
为不同的实现算 法构造抽象接口,利用delegation,运行时动态传入client倾向的算法 类实例
15 模板模式
共性的步骤在抽象类内公共实现,差 异化的步骤在各个子类中实现
使用继承和重写实现模板模式