可复用性复习概要

  1. 可复用的不仅仅只有代码,最主要的复用是在代码层面, 但软件构造过程中的任何实体都可能被复用,如需求、设计/规约spec、数据、测试用例、文档。

  2. 代码复用的类型:
    (1) 白盒复用:源代码可见,可修改和扩展。通过继承进行复用。
    (1) 黑盒复用:源代码不可见,不能修改。通过实现接口/委托复用。

  3. 设计可复用的类:继承与重写、重载、参数多态与泛型编程、行为子类型与Liskov替换原则、组合与委托。

  4. Liskov替换原则:
    子类型可以增加方法,但不可删;
    子类型需要实现抽象类型中的所有未实现方法;
    子类型中重写的方法必须有相同或子类型的返回值或者符合co-variance的参数;
    子类型中重写的方法必须使用同样类型的参数或者符合contra-variance的参数;
    子类型中重写的方法不能抛出额外的异常;
    更强的不变量;
    更弱的前置条件;更强的后置条件(规约更强)。

    (斜体加粗部分不可被Java静态检测检查出来)
    更强的不变量例子(子类型应当完整保持父类型中属性的RI,不能改变,可以增加新的属性的RI):
    可复用性复习概要_第1张图片

  5. 协变与反协变
    协变:对于同一个方法,子类的返回值比父类更确切。
    可复用性复习概要_第2张图片
    反协变:对于同一个方法,子类的参数比父类更抽象。(编译器不支持,java将其当作重载看待)
    可复用性复习概要_第3张图片
    父类型->子类型:越来越具体specific
    参数类型:要相反的变化,要不变或越来越抽象。

  6. Java中数组是支持协变的:
    可复用性复习概要_第4张图片
    图中最后一条语句错误是因为这是赋值操作,调用了valueOf(),不会进行转换。

  7. 泛型中的LSP
    可复用性复习概要_第5张图片
    例子:
    可复用性复习概要_第6张图片
    当带通配符“?”时,list间可以存在父子关系。"?":任意类;"":A和A的父类;"":A和A的子类。
    例:List is a subtype of List

  8. ADT比较大小:
    (1) 实现Comparator接口并override compare()函数
    (2) 让你的ADT实现Comparable接口,然后override
    compareTo() 方法。

  9. 委托的方式:
    (1) 临时性委托:通过方法的参数委托
    可复用性复习概要_第7张图片
    (2) 永久性委托:通过属性委托。又分为聚合(Aggregation: 更弱的association,可动态变化)和组合( Composition: 更强的association,但难以变化)。
    聚合:
    可复用性复习概要_第8张图片
    组合:
    可复用性复习概要_第9张图片

  10. 白盒框架:基于继承,子类对象执行;
    黑盒框架:基于接口,框架执行。

  11. 面向复用的设计模式。
    (1) 设计(Structural)模式
    (a) 适配器(Adapter)模式:解决接口不匹配的问题
    可复用性复习概要_第10张图片
    (b) 装饰(Decorator)模式:为对象增加不同侧面的特性,这些属性可以任意组合。
    可复用性复习概要_第11张图片
    例子:
    可复用性复习概要_第12张图片
    可复用性复习概要_第13张图片
    (c) 门面(Facade)模式:提供一个统一的接口来取代一系列小接口调用,相当于对复杂系统做了一个封装,简化客户端使用。
    例子:
    可复用性复习概要_第14张图片
    使用门面模式后:
    可复用性复习概要_第15张图片
    使用:
    可复用性复习概要_第16张图片
    (2) 行为(Behavioral)模式
    (a)策略(Strategy)模式:有多种不同的算法来实现同一个任务,但需要client根据需要动态切换算法,而不是写死在代码里
    (b) 模板(Template)模式:共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现,如白盒框架(继承)。
    (c)迭代器(Iterator)模式:让自己的集合类实现Iterable接口,并实现自己的独特Iterator迭代器(hasNext, next, remove),允许客户端利用这个迭代器进行显式或隐式的迭代遍历。

你可能感兴趣的:(可复用性复习概要)