软件构造学习笔记-第九周

框架层面的复用

1.可分为白盒框架和黑盒框架
白盒框架:通过子类型和重写方法实现扩展,对应模板模式
黑盒框架:通过插件接口实现扩展(本质上是委托),对应策略模式和观察模式
2.复用白盒框架后,通过创建子类进行调用。
软件构造学习笔记-第九周

复用黑盒调用后,通过框架程序进行调用。
软件构造学习笔记-第九周

3.白盒框架和黑盒框架可复用代码的位置
黑盒的可复用代码在框架中,插件是自定义部分
白盒框架的可用代码是子框架的父类
软件构造学习笔记-第九周

结构模式

1.适配器Adapter
① 使用具有中转功能的接口,将不匹配的接口统一(将某个类或接口转换为用户期望的其他形式)
软件构造学习笔记-第九周

②Rectangle类是adapter,LegacyRectangle是adaptee
软件构造学习笔记-第九周

2.装饰器Decorator
①让类的操作产生更多的特性,对每一个特性构造子类,通过委派机制增加到对象上。
②例子:stack的三种附加功能
软件构造学习笔记-第九周

上面是接口,左边是被扩充的类,右边是装饰。装饰类中将基础操作,比如push、pop、size操作,通过引用委托到左边的被扩充类完成。
装饰类委托的类不同,可以实现层层装饰的效果。比如在实现SecureStack时,将其父类StackDecorator指向UndoStack,则实现的SecureStack就同时具有了UndoStack功能。如果同时,将UndoStack的父类指向LockedStack,UndoStack就具有了LockedStack功能。
装饰类只能使用接口中的操作。
具体例子:
软件构造学习笔记-第九周
软件构造学习笔记-第九周
软件构造学习笔记-第九周
软件构造学习笔记-第九周

注:t无法使用undo方法,只能使用接口中的push、pop、size方法。
3.外观模式Facade
①组合接口成一个统一的接口,Lab3中有体现。

行为模式

1.策略模式Strategy
①某个接口(通用)有多个实现,使用委托,根据不同实际情况进行调用切换。
2.模板模式Template method
①使用继承和重写实现。一个类作为模板,用子类进行继承和扩充。共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现。
3.迭代器Iterator
①用迭代器对集合进行操作。客户端希望遍历被放入容器/集合类的一组ADT对象,无需关心容器的具体类型。即是不管对象被放进哪里,都提供同样的遍历方式。
②迭代器是可变类。使用时集合中的当前对象有两个引用,一个来自集合,另一个来自迭代器。所以不使用迭代器遍历时不能删除元素,即只能使用迭代器的remove进行删除。

可维护性的度量与构造原则

1.软件维护的种类:纠错性、适应性、完善性、预防性
2.提高可维护性的方法:
从原则上通过模块化。
OO设计原则(SOLID、GRASP)
OO设计模式
基于状态的构造技术
基于语法的构造技术(正则表达式)

模块化设计

1.模块化设计的原则:直接映射、尽可能少的接口、尽可能小的接口、显式接口、信息隐藏
2.耦合和内聚
软件构造学习笔记-第九周

3.OO设计原则-SOLID
①单一责任原则
不应该有多于一个的原因让ADT发生变化,否则就应该拆分开。责任就是变化的原因,即一个类承担一个责任。
②开放-封闭原则
对扩展性的开发,对修改的封闭。模块的行为是可扩展的,从而该模块可表现出新的行为以满足需求的变化。但是模块自身的代码是不应被修改的,扩展模块行为的一般途径是修改模块的内部实现,如果一个模块不能被修改,那么它通常被认为是具有固定的行为。
针对多个实现抽象出一个具体的接口,如果有新的实现,继承该接口即可。从而支持了对扩展的开放。
软件构造学习笔记-第九周
软件构造学习笔记-第九周

③Liskov替换原则***
子类型必须能够替换其父类型,派生类必须能够通过其基类的接口使用,客户端无需了解二者之间的差异。
④依赖转置原则
尽量依赖接口,而不是接口的具体实现类。抽象的模块不应该依赖于具体的模块,具体应该依赖于抽象。
软件构造学习笔记-第九周

⑤接口分离原则
只提供客户端必需的接口。
软件构造学习笔记-第九周
软件构造学习笔记-第九周