软件构造课笔记:第11章——面向可复用性和可维护性的设计模式

面向可复用性和可维护性的设计模式

设计模式分类法
1.创建型模式:关注对象创建过程
2.结构型模式:处理类或对象的组合
3.行为类模式:描述类或对象交互和分配责任的方式。

创建型模式

工厂方法模式

        当 client 不知道要创建哪个具体类的实例,或者不想在 client 代码中指明要具体 创建的实例时,用工厂方法。 定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个 类的实例化延迟到其子类。

Client使用 “工厂方法” 来创建实例, 得到实例的类型是抽象接口而非具体类。有新的具体产品类 加入时,可以在工厂类里修改或增加 新的工厂函数 (OCP),不会影响客户端代码。interface不仅包含 factory method, 还可以实现其他功能。可以根据类型决定创建哪个具体产品。静态工厂方法既可以在ADT 内部实现,也可以构造单独的工厂类


有利条件
消除了将特定于应用程序的类绑定到代码的需要。
代码只处理产品接口(Trace),因此它可以与任何用户定义的ConcreteProduct(FileTrace、SystemTrace)一起工作

潜在的缺点
客户端可能必须创建Creator的子类,以便创建特定的ConcreteProduct。
如果客户端无论如何都必须对创建者进行子类化,这是可以接受的,但如果不是,那么客户端必须处理另一个进化点。

开闭原理(OCP):对扩展的开放,对修改已有代码的封闭

结构型模式
适配器模式

将某个类 / 接口转换为 client 期望的其他形式。通过增加一个接口,将已存在 的子类封装起来,client面向接口编程,从而隐藏了具体子类。

装饰器模式

继承模式有很大限制,可能出现组合爆炸以及大量的代码重复

需要对单个对象进行任意或动态可组合的扩展。为对象增加不同侧面的特性

解决方案:将通用接口实现为要扩展的对象,添加功能,但将主要责任委派给底层对象。对每一个特性构造子类,通过委派机制增加到对象上

优点:比静态继承更灵活–可定制、有凝聚力的扩展

装饰器与继承对比
1.装饰器在运行时编写功能,继承在编译时组成特性
2.装饰器由多个协作对象组成,继承产生一个明确类型的对象
3.可以混合搭配多种装饰,多重继承在概念上很困难

行为类模式

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

模板模式/模板方法


问题:几个客户端共享相同的算法,但在细节上有所不同,即一个算法由可定制的部分和不变的部分组成。公共步骤不应在子类中重复,而是需要重用。

解决方案
算法的常见步骤被分解到一个抽象类中,抽象(未实现)基元操作表示算法的可定制部分。共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现,子类为这些步骤中的每一个提供了不同的实现。

使用继承和重写实现模板模式,而策略模式使用委托来改变整个算法(接口和自组织多态性)。

迭代器

问题:客户端需要统一的策略来访问容器中的所有元素,与容器类型无关客户端希望遍历被放入
容器/集合类的一组ADT对象,无需关心容器的具体类型,也就是说,不管对象被放进哪里,都应该提供同样的遍历方式
解决方案:迭代的策略模式

Iterator pattern:让自己的集合类实现Iterable接口,并实现自己的 独特Iterator迭代器(hasNext, next, remove),允许客户端利用这个迭代器进行显式或隐式的迭代遍历

访问者

访问者模式:允许在运行时对一组对象应用一个或多个操作,将操作与对象结构解耦,二者动态绑定到一起,该操作可以灵活更改,无需更改被访问,Visitor模式实际所做的是创建一个使用其他类中数据的外部类。如果操作的逻辑发生了变化,那么我们只需要在访问者实现中进行更改,而不需要在所有项类中进行更改。

本质上:将数据和作用于数据上的某种/些特定操作分离开来。为ADT预留一个将来可扩展功能的“接入点”,外部实现的功能代码 可以在不改变ADT本身的情况下通过代表团

策略与访客模式

二者都是通过delegation建立两个对象的动态联系,但是Visitor强调是的外部定义某种对ADT的操作,该操作于ADT自身关系 不大(只是访问ADT),故ADT内部只需要开放accept(visitor)即可,client 通过它设定visitor操作并在外部调用。而Strategy则强调是对ADT内部某些要实现的功能的相应算法的灵活替换。 这些算法是ADT功能的重要组成部分,只不过是delegate到外部strategy类 而已。

区别:visitor是站在外部client的角度,灵活增加对ADT的各种不同操 作(哪怕ADT没实现该操作),strategy则是站在内部ADT的角度, 灵活变化对其内部功能的不同配置


设计模式的共性与差异

只使用“继承”,不使用“delegation” 核心思路:OCP/DIP
依赖反转,客户端只依赖“抽象”,不能 依赖于“具体”
发生变化时最好是“扩展”而不是“修改”

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

Template:适用场合:有共性的算法流程, 但算法各步骤有不同的实现 典型的“将共性提升至超类型, 将个性保留在子类型”。注意:如果某个步骤不需要有 多种实现,直接在该抽象类里 写出共性实现即可

Strategy:根据OCP原则,想有多个算法的实现, 在右侧树里扩展子类型即可,在左侧 子类型里传入不同的类型实例


 

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值