16-设计模式
设计模式是设计经验的总结。
本章只是介绍《设计模式》中最为简单、常用的几种设计模式,它们都是用来提高系统可修改性的。
1. 可修改性及其基本实现机制
- 实现的可修改性:涉及到大的场景的修改
- 对已有实现的修改
- 使用接口与实现分离即可实现可修改性,对实现作修改,不影响client类
- 实现的可扩展性(DIP & OCP)
- 对新的实现的扩展
- 使用接口与实现分离即可实现可拓展性,增加一个新的类即可
- 实现的灵活性
- 对实现的动态配置
- 多态,根据对象的实际类型调用方法
1.1. 如何实现可修改性? 重要
- 接口与实现的分离
1.2. 如何将接口与实现的分离 – Java视角
- 通过接口与实现该接口的类,将接口与实现相分离
- 通过子类继承父类/抽象类,将父类的接口与子类的实现相分离:通过继承的方式,在一定程度上实现了接口与实现的分离,但是也使得子类继承了父类的实现,当然可以更好地重用代码,但使得灵活性略有下降【父类接口改变,子类一定会变】。
1.3. 实现接口(interface)
- interface:定义了规约
- 实现class:实现了规约
1.4. 类图中的标志物的含义
- 虚线箭头:依赖
- 实线箭头:关联(两侧写数量)
- 空菱形在一侧的实线箭头:聚合
- 实菱形在一侧的实线箭头:组合
- 空心实线箭头:泛化(extends)
- 空心虚线箭头:实现(implements)
1.5. 类图与依赖关系
- Client、Interface_A、Class_A1之间是什么关系?
- Client和Class_A1是否存在依赖关系?
1.6. 继承
- 父类定义了规约(contract)
- 子类实现了规约(contract)
1.7. 类图与依赖关系
- Client、Super_A、Sub_A1之间是什么关系?
- Client和Sub_A1是否存在依赖关系?不
1.8. 实现的可修改性
- 对于实现的可修改性,无论是Class_A1还是Sub_A1的method_A方法的实现的修改都和Client中的调用代码没有任何耦合性。
1.8.1. 扩展
1.9. 实现的可扩展性
- 对于实现的可扩展性,我们可以通过 Class_A2还是Sub_A2的创建来实现。
1.10. 实现的灵活性
1.11. 继承的优点
- 虽然继承也能很好的完成接口与实现的分离,但是继承还有他独有的特征。
- 子类不但继承了父类的接口还继承了父类的实现,这可以更好的进行代码的重用。
1.12. 继承的缺点
- 继承的父类与所有子类存在共有接口的耦合性。当父类接口发生改变的时候,子类的接口就一定会更改,这样就会影响到 Client代码。
- 而且当子类创建对象的时候,就决定了其实现的选择,没法再动态的修改。即只能单继承,不能多继承,而接口可以多实现
1.13. 组合
- 而利用接口的组成关系,却能在实现接口和实现的前提下,体现更好的灵活性。前端类和后端类是组合关系。前端类重用了后端类的代码。
- 考虑到软件工程中的人的重要性。
1.13.1. 组合的优点
- 前端和后端在接口上不存在耦合性。当后端接口发生改变的时候,只要在 frontend 里面修改即可,并不会直接影响到Client代码。
- 后端类的实现亦可以动态创建、动态配置、动态销毁,非常灵活。
2. 设计模式
2.1. Why?为什么使用设计模式
- 设计OO软件非常困难
- 设计可重用的OO软件-难度更大
- 经验丰富的OO设计师可以做出出色的设计
- 新设计师倾向于使用以前使用的非OO技术
- 经验丰富的设计师知道一些东西-这是什么?
- 专家设计师知道不能从第一原则中解决所有问题
- 复用的解决方案
- 这些模式使面向对象的设计更加灵活,优雅并且最终可重用。
2.2. 什么是设计模式
- 设计模式:抽象一个重复的设计结构
- 包含类和/或对象
- 依赖
- 结构
- 互动,或
- 约定
- 提炼设计经验
2.3. 模式
- 典型问题
- 设计分析
- 解决方案
- 案例
2.4. 解决方案
- 参与者与协作:描述了设计中涉及的各个类的组成成分,他们之间的相互关系及各自的职责和协作方式。
- 应用场景:描述了应该何时使用模式。它解释了设计模式所要解决的问题,以及解决这个问题时所面临的特点的环境、限制条件、场景等。这也是我们在应用某种模式之前,需要仔细去体察的。
- 使用注意点:因为模式只是一个模板,他可以应用与多种不同场合,所以解决方案并不描述一个具体的实现,而是提供解决方案的一个抽象模型。要根据具体情况来具体实现
3. 设计模式和策略配对
:star:详见书本 p265
各个设计模式使用的设计原则:
-
策略模式:【强调行为的不同】
- 减少耦合:减少策略的使用类和策略的实现类直接的耦合
- 依赖倒置:策略的使用类依赖的是策略的接口,而非策略的实现类。
-
抽象工厂模式:【强调对象的创建】
- 职责抽象:抽象对于对象创建的职责
- 接口重用:提供对于对象创建的接口
-
单件模式:
- 职责抽象:隐藏单件创建的实现
- 信息隐藏
-
迭代器模式:【偏向于完成遍历集合这个业务】
其实是个工厂模式,用于创建 iterator,但使用得太多了,因此单独分出来作为一个模式
- 减少耦合:减少遍历的使用类和遍历的实现类直接的耦合
- 依赖倒置:遍历的使用类依赖的是策略的接口,而非遍历的实现
4. 设计模式重点掌握类图 重要
-
策略模式:组合的方式,如果是继承也可以,但不易维护
-
抽象工厂模式
-
工厂模式
-
抽象工厂模式【相比于工厂模式多了一层抽象,注意这里的ConcreteFactory1和2都可以创建产品A和B】
-
-
单件模式
-
迭代器模式
5. 题目
- 给定场景,利用设计模式写出代码
- 给出代码,利用设计模式重写
- 设计模式内容具体查看