软件构造复习——面向可复用性和可维护性的设计模式(PPT11)

在这里插入图片描述

设计模式分类
§创作模式
– 工厂方法模式在不指定确切类的情况下创建对象。
§ 结构模式
– 适配器允许具有不兼容接口的类通过将自己的接口包装在现有类的接口周围来协同工作。
– 装饰器动态添加/覆盖对象方法中的行为。
§ 行为模式
– 策略允许在运行时选择一系列算法中的一个。
– 模板方法将算法的骨架定义为抽象类,允许其子类提供具体的行为。
– 迭代器按顺序访问对象的元素,而不暴露其底层表示。
– 访问者通过将方法层次结构移动到一个对象中来将算法与对象结构分开。


在这里插入图片描述

一个设计…
…使更改的灵活性成为可能(可重用性)
…在修复旧问题时最大限度地减少新问题的引入
(可维护性)
…允许在初始交付后交付更多功能
(可扩展性)。
设计模式:针对软件设计中给定上下文中常见问题的通用的、可重用的解决方案。
OO 设计模式通常显示类或对象之间的关系和交互,而不指定所涉及的最终应用程序类或对象。

一、创建模式(Creational patterns)

1.1 工厂方法模式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
使用工厂方法时,一定要使用接口!!!!用接口来实现对象的构造。

普通工厂方法需要new
静态工厂直接就可以调用静态方法构造

工厂方法
§ 优势:
– 无需将特定于应用程序的类绑定到您的代码。
– 代码只处理产品接口(Trace),因此它可以与任何用户定义的具体产品(FileTrace、SystemTrace)一起使用
§ 潜在的缺点
– 客户可能必须创建 Creator 的子类,以便他们可以创建特定的 ConcreteProduct。
– 如果客户端无论如何都必须对 Creator 进行子类化,这是可以接受的,但如果不是,则客户端必须处理另一个进化点。
§ 开闭原则(OCP)
——对扩展的开放,对现有代码的封闭

二、结构模式

2.1 适配器模式

在这里插入图片描述

意图:将一个类的接口转换成客户期望得到的另一个接口。
(将某类/接口转化为客户期望的其他形态)
– 适配器让那些因为接口不兼容而不能一起工作的类一起工作。
– 用新接口包装现有类。
(通过增加一个接口,将已的子类封装起来,客户存在实例模型,从而隐藏具体的子类。)
§ 对象:将旧组件重用于新系统(也称为“包装器”)

在这里插入图片描述

LegacyRectangle 组件的 display() 方法期望接收“x、y、w、h”参数。
§ 但是客户端想要传递“左上角的 x 和 y”和“右下角的 x 和 y”。
§ 这种不一致可以通过添加一个额外的间接级别来解决——即一个适配器对象。 ----委托
在这里插入图片描述
在这里插入图片描述
当想要调用另一个类的方法时,传入的参数不匹配,需要中间加一个适配器(先利用接口创建一个实现类,接口(接口中有和该方法相同输入类型的方法),对接口的实现类(对接口传入的参数进行改变调整,达到允许调用的情况)之后就可以实现了,这就是“适配”)
在这里插入图片描述

2.2 装饰器模式

在这里插入图片描述

问题:您需要对单个对象进行任意或动态组合扩展。 为对象增加了不同的特性
§ 解决方案:实现一个通用接口作为您要扩展的对象,添加功能,但将主要责任委托给底层对象。
§ 结果:
– 比静态继承更灵活
– 可定制的、有凝聚力的扩展
§ 装饰器同时使用子类型和委托

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

装饰器与继承
§ 装饰器在运行时组合功能
– 继承在编译时组合功能
§ 装饰器由多个协作对象组成
– 继承产生一个单一的、明确类型的对象
§ 可以混搭多种装饰
– 多重继承在概念上很困难
在这里插入图片描述

2.3行为模式

2.3. (1) 策略模式(考)

在这里插入图片描述

问题:针对特定任务存在不同的算法,但是客户端可以在运行时根据动态上下文在算法之间切换。
有多种不同的算法来实现同一个任务,但需要客户根据需要动态切换算法,而不是写死在代码里
§ 示例:排序客户列表(气泡排序、合并排序、快速排序)
§ 解决方案:为算法创建一个接口,为算法的每个变体创建一个实现类。
为不同的实现算法构造抽象接口,利用代表团运行时动态传入客户倾向的算法类实例
§ 优势:
–易于扩展以实现新的算法
–将算法与客户端上下文分离
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
把功能实现用接口委托出去

2.3.(2) 模板模式

在这里插入图片描述

问题:多个客户机共享相同的算法,但在细节上有所不同,即算法由可定制部分和不变部分组成。子类中的公共步骤不应重复,但需要重用。
– 做事情的步骤一样,但具体方法不同
§ 示例:
–执行测试用例的测试套件
–打开、阅读、编写不同类型的文件
§ 解决方案:
–算法的常见步骤被分解成一个抽象类,抽象(未实现)的原始操作表示算法的可定制部分。
共性的步骤在抽象类内公共实现,差异化的步骤在各个子类中实现
–子类为每个步骤提供不同的实现

在这里插入图片描述

模板方法模式使用继承+可重写方法来改变算法的一部分使用继承和重写实现模板模式
–而策略模式使用委托来改变整个算法(接口和特殊多态性)。
§ 模板方法在框架中有着广泛的应用
–该框架实现了算法的不变量
–客户端定制为算法提供了专门的步骤
–原则:“不要打电话给我们,我们会打电话给你”

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2.3.(3) 迭代器模式

在这里插入图片描述

问题:客户机需要统一的策略来访问容器中的所有元素,独立于容器类型
客户端希望遍历被放入容器/集合类的一组ADT公司对象,无需关心容器的具体类型
– 也就是说,不管对象被放进哪里,都应该提供同样的遍历方式
§ 解决方案:迭代的策略模式
§ 后果:
–隐藏底层容器的内部实现
–支持具有统一接口的多种遍历策略
–易于更换容器类型
–促进项目各部分之间的沟通

在这里插入图片描述
–抽象迭代器类定义遍历协议
–每个聚合类的具体迭代器子类
–聚合实例创建迭代器对象的实例
–聚合实例保留对迭代器对象的引用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.(4) 观察者模式

在这里插入图片描述
访问者模式:允许在运行时将一个或多个操作应用于一组对象,从而将操作与对象结构分离。
Visitor模式实际上是创建一个使用其他类中的数据的外部类。
–如果操作逻辑发生了变化,那么我们只需要在visitor实现中进行更改,而不是在所有item类中进行更改。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

迭代器:行为模式,用于顺序访问聚合而不暴露其底层表示。 因此,您可以在迭代器后面隐藏列表或数组或类似的聚合。

迭代器:以遍历的方式访问集合数据而不暴露其内部表示,将“遍历”这个功能委托到外部的迭代器对象。

访问者:行为模式,用于在不改变元素本身的实现的情况下对元素结构执行操作。

在特定的 ADT 上执行特定的操作,但该操作不在 ADT 内部实现,频率委托到独立的访客对象,客户端可灵扩展/改变访客的操作运算,而不影响 ADT

在这里插入图片描述

三、设计模式的共性与差异

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_50906780/article/details/118459442