Software Reuse

优点:降低成本和开发时间;经过充分测试,可靠、稳定;标准化,在不同应用中保持一致。

缺点:开发可复用的软件(性能差,缺少针对性)和使用已有软件进行开发(需要适配)都需要代价。

measure “reusability”:复用的机会有多频繁;复用的代价有多大(搜索、获取,适配、扩展,实例化,与软件其他部分的互连的难度)

最主要的复用是在代码层面,但软件构造过程中的任何实体都可能被复用(包括需求、规约spec、数据、测试用例、文档等)

  • Source code level: methods, statements, etc (lowest level)

  • Module level: class and interface

  • Library level: API (Java Library, .jar)

  • Architecture level: framework 框架

  • 白盒复用:源代码可见,可修改和扩展(继承)。复制已有代码到正在开发的系统,进行修改;Pro:可定制化程度高;Con:对其修改增加了软件的复杂度,且需要对其内部充分的了解。

  • 黑盒复用:源代码不可见,不能修改(委托)。 只能通过API接口来使用,无法修改代码;Pro:简单清晰;Con:适应性差。

框架:一组具体类、抽象类、及其之间的连接关系。开发者根据framework的规约,填充自己的代码进去,形成完整系统。

Whitebox frameworks 白盒框架,通过代码层面的继承和动态绑定进行框架扩展。

Blackbox frameworks 黑盒框架,通过实现特定接口/delegation进行框架扩展。

Designing reusable classes

Behavioral subtyping 行为子类型与 Liskov 可替换原则 (LSP)

委托与组合

Behavioral subtyping and Liskov Substitution Principle (LSP)

行为子类型

Compiler-enforced rules in Java (static type checking) - 子类型可以增加方法,但不可删 - 子类型需要实现抽象类型中的所有未实现方法 - 子类型中重写的方法必须有相同或子类型的返回值或者符合co-variance(协方差)的参数 - 子类型中重写的方法必须使用同样类型的参数或者符合contra-variance(反方差)的参数 - 子类型中重写的方法不能抛出额外的异常

指定行为(方法) - 更强的不变量 - 更弱的前置条件 - 更强的后置条件

LSP

LSP

Covariance 协变:父类型->子类型:越来越具体specific或者不变(返回值类型、异常的类型)。@override

Contravariance 反协变、逆变:父类型->子类型:越来越抽象或者不变(参数类型)。目前Java中遇到这种情况,当作overload看待。

Arrays are covariant 协变的:an array of type T[] may contain elements of type T or any subtype of T