第9讲
面向复用的软件构造技术
What is Software Reuse?
Why reuse?
降低成本和开发时间。经过充分 测试,可靠、稳定。标准化,在不同应用中保持一致。
Reuse costs
做到这些,需要代价。不仅 program for reuse代价高,某些情况下program with reuse代价也高。
Development for reuse: 开发可复用的软件
开发成本 高于一般软件的成本:要有足够高的适应性。性能差些: 针对更普适场景,缺少足够的针对性。
Development with reuse: 使用已有软件进行开发
可复用软件库,对其进行有效的管理。adaptation 往往无法拿来就用,需要适配。
如何衡量“可复用性”?
衡量“可复用性”:复用的机会有多频繁?复用的场合有多少?复用的代价有多大?(搜索、获取,适配、扩展,实例化,与软件其他 部分的互连的难度)
A software asset with high reusability should:
小、简单
与标准兼容
灵活可变
可扩展
泛型、参数化
模块化
变化的局部性
稳定
丰富的文档和帮助
可复用组件的级别和形态
最主要的复用是在代码层面
但软件构造过程中的任何实体都可能被复用
– Requirements 需求
– Design and specifications 设计/规约spec
– Data 数据
– Test cases 测试用例
– Documentation 文档
Types of Code Reuse
白盒复用:源代码可见,可修改和扩展(复制已有代码到正在开发的系统,进行修改;可定制化程度高;对 其修改增加了软件的复杂度,且需要对其内部充分的了解)
黑盒复用:源代码不可见,不能修改(只能通过API接口来使用,无法修改代码;简单,清晰;适应性差些)
白盒框架,通过代码层面的继承进行框架扩展
黑盒框架,通过实现特定接口/delegation进行 框架扩展
LSP
Covariance (协变) 父类型→子类型:越来越具体specific 返回值类型:不变或变得更具体 异常的类型:也是如此。
Contravariance (反协变、逆变) 父类型→子类型:越来越具体specific 参数类型:要相反的变化,要不变或越来 越抽象
----------------------------------------------------------------------------------------------------------------------------
第10讲
软件维护的类型
纠错性,适应性,完善性,预防性
可维护性的常见度量指标
可维护性,可扩展性,灵活性,可适应性,可管理性,支持性
评估模块化的五个标准
▪ Decomposability (可分解性)
▪ Composability (可组合性)
▪ Understandability (可理解性)
▪ Continuity (可持续性) ——发生变化时受影响范围最小
▪ Protection (出现异常之后的保护) ——出现异常后受影响范围最小
模块化设计的五个规则
▪ Direct Mapping (直接映射)
▪ Few Interfaces (尽可能少的接口)
▪ Small Interfaces (尽可能小的接口)
▪ Explicit Interfaces (显式接口)
▪ Information Hiding (信息隐藏)
聚合度与耦合度
Coupling(耦合)模块间的接口数目,每个接口的复杂度
Cohesion
SOLID
▪ (SRP) The Single Responsibility Principle 单一责任原则
▪ (OCP) The Open-Closed Principle 开放-封闭原则
▪ (LSP) The Liskov Substitution Principle Liskov替换原则
▪ (DIP) The Dependency Inversion Principle 依赖转置原则
▪ (ISP) The Interface Segregation Principle 接口聚合原则
语法驱动的构造
正则表达式
Parse Trees
----------------------------------------------------------------------------------------------------------
第11讲
Adapter适配器模式
将某个类/接口转换为client期望的其他形式。解决类之间接口不兼容的问题。通过增加一个接口,将已存在 的子类封装起来,client面向接口编程,从而隐藏了具体子类。加个“适配器”以便于复用
Decorator装饰器模式
Strategy 策略模式
有多种不同的算法来实现同一个任务,但需要client根据需要 动态切换算法,而不是写死在代码里。为不同的实现算 法构造抽象接口,利用delegation,运行时动态传入client倾向的算法 类实例。
Template Method 模板模式
做事情的步骤一样,但具体方法不同。共性的步骤在抽象类内公共实现,差 异化的步骤在各个子类中实现。模板方法定义了一个算法的步骤,并允许子 类为一个或多个步骤提供实现。使用继承和重写实现模板模式。
Iterator
客户端希望对放入容器 /集合类的一组ADT对象进行遍历访问,而无需关心容器的具体类型 – 也就是说,不管对象被放进哪里,都应该提供同样的遍历方式。
Visitor
对特定类型object的特定操作(visit),在运行时将二 者动态绑定到一起,该操作可以灵活更改,无需更改被visit的类。本质上:将数据和作用于数据上的某种/些特定操作分离开来。 为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码 可以在不改变ADT本身的情况下在需要时通过delegation接入ADT。
factory method