SoftwareConstruction——Reusable

1. 可复用性的概念

programming for reuse 面向复用编程:开发出可复用的软件
programming with reuse 基于复用编程:利用已有的可复用软件搭建应用系统

优点

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

SoftwareConstruction——Reusable

2. 面向复用的软件构造技术

Liskov Substitution Principle 里氏替换原则(LSP)

  • 子类型多态:客户端可用统一的方式处理不同类型的对象
  • 在可以使用父类的场景,都可以用子类型代替而不会有任何问题

编译强制规则

  • 子类型可以增加方法,但不可删除方法
  • 子类型需要实现抽象类型中的所有未实现方法
  • 协变:子类型中重写的方法必须有相同或子类型的返回值或者符合co-variance的参数
  • 逆变:子类型中重写的方法必须使用同样类型的参数或者符合contra-variance的参数
  • 子类型中重写的方法不能抛出额外的异常

Also applies to specified behavior (methods):

  • Same or stronger invariants 更强的不变量
  • Same or weaker preconditions 更弱的前置条件
  • Same or stronger postconditions 更强的后置条件

协变 & 反协变

父类型 → 子类型:

  • 协变:返回值和异常不变或越来越具体
  • 逆变(反协变):参数类型要相反地变化,要不变或越来越抽象

SoftwareConstruction——Reusable

泛型
泛型类型是不支持协变的:

ArrayList<String>List<String>的子类型,但List<String>不是List<Object>的子类型

这是因为发生了类型擦除,运行时就不存在泛型了,所有的泛型都被替换为具体的类型。

但是在实际使用的过程中是存在能够处理不同的类型的泛型的需求的,如定义一个方法参数是List<E>类型的,但是要适应不同的类型的E,于是可使用通配符解决这个需求:

无类型条件限制:

当为A类型的父类型

当为A类型的子类型

委派(Delegation)
一个对象请求另一个对象的功能
通过运行时动态绑定,实现对其他类中代码的动态复用

“委托”发生在object层面
“继承”发生在class层面

SoftwareConstruction——Reusable

SoftwareConstruction——Reusable

Types of Delegation:

依赖 Dependency:临时性的delegation

  • 把被delegation的对象以参数方式传入。只有在需要的时候才建立与被委派类的联系,而当方法结束的时候这种关系也就随之断开了。

关联 Association:永久性的delegation

  • 分为:组合(Composition)聚合(Aggregation)
  • 被delegation的对象保存在rep中,该对象的类型被永久的与此ADT绑定在了一起。

组合 Composition:更强的Association,但难以变化

  • 在rep或构造方法中设定

聚合 Aggregation:更弱的Association,可动态变化

  • 在构造方法中传入参数绑定

组合(Composition)和CRP原则

  • 利用delegation的机制,将功能的具体实现与调用分离,在实现中又通过接口的继承树实现功能的不同实现方法,而在调用类中只需要创建具体的子类型然后调用即可。组合就是多个不同方面的delegation的结合。

SoftwareConstruction——Reusable
  • 抽象层是不会轻易发生变化的,会发生变化的只有底层的具体的子类型,而具体功能的变化(实现不同的功能)也是在最底层,所以抽象层是稳定的。而在具体层,两个子类之间的委派关系就有可能是稳定的也有可能是动态的,这取决于需求和设计者的设计决策。

SoftwareConstruction——Reusable

白盒框架 & 黑盒框架的原理与实现

黑盒框架

  • 通过实现特定接口进行框架扩展,采用的是delegation机制达到这种目的,通常采用的设计模式是策略模式(Strategy)和观察者模式(Observer);
  • 黑盒所预留的是一个接口,在框架中只调用接口中的方法,而接口中方法的实现就依据派生出的子类型的不同而不同,它的客户端启动的就是框架本身。

白盒框架

  • 通过继承和重写实现功能的扩展,通常的设计模式是模板模式(Template Method);
  • 白盒框架所执行的是框架所写好的代码,只有通过override其方法来实现新的功能,客户端启动的的是第三方开发者派生的子类型。

3. 面向复用的设计模式

Adapter 适配器模式

将某个类/接口转换为client期望的其他形式
增加接口

  • 通过增加一个接口,将已存在的子类封装起来
  • client面向接口编程,从而隐藏了具体子类。

适用场合:你已经有了一个类,但其方法与目前client的需求不一致。
根据OCP原则,不能改这个类,所以扩展一个adaptor和一个统一接口。

SoftwareConstruction——Reusable

Decorator 装饰者模式

继承组合会引起组合爆炸/代码重复

  • 为对象增加不同侧面的特性
  • 对每一个特性构造子类,通过委派机制增加到对象上
  • 客户端需要一个具有多种特性的object,通过逐层的装饰来实现

SoftwareConstruction——Reusable

例子:

  • Stack对应上图Component接口
  • ArrayStack对应ConcreteComponent,基础类
  • StackDecorator对应Decorator,装饰类(可以是抽象类)
  • UndoStack对应ConcreteDecoratorA,装饰类的具体类
  • 使用装饰对象:层层嵌套初始化new Class1(new Class2(new Class3(…)))

JDK中装饰器模式的应用:
static List<T> unmodifiableList(List<T> list)
static Set<T> synchronizedSet(Set<T> set)

facade 外观模式

  • 客户端需要通过一个简化的接口来访问复杂系统内的功能
  • 提供一个统一的接口来取代一系列小接口调用,相当于对复杂系统做了一个封装,简化客户端使用
  • 便于客户端学习使用,解耦

SoftwareConstruction——Reusable

Strategy 策略模式

  • 有多种不同的算法来实现同一个任务
  • 但需要client根据需要动态切换算法,而不是写死在代码里
  • 为不同的实现算法构造抽象接口,利用delegation,运行时动态传入client倾向的算法类实例

SoftwareConstruction——Reusable

Template Method 模板方法模式

  • 框架:白盒框架
  • 做事情的步骤一样,但具体方法不同
  • 共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现
  • 使用继承和重写实现模板模式

SoftwareConstruction——Reusable

适用场合:有共性的算法流程,但算法各步骤有不同的实现典型的“将共性提升至超类型,将个性保留在子类型”

Iterator 迭代器模式

客户端希望遍历被放入容器/集合类的一组ADT对象,无需关心容器的具体类型
也就是说,不管对象被放进哪里,都应该提供同样的遍历方式

实现方式是在ADT类中实现Iterable接口,该接口内部只有一个返回一个迭代器的方法,然后创建一个迭代器类实现Iterator接口,实现hasnext()、next()、remove()这三个方法。
 

文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树首页概览91499 人正在系统学习中

来源:MaklutMyu

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年6月3日
下一篇 2021年6月3日

相关推荐