敏捷软件开发 第十三章~第十七章

这几章主要讲了几个设计模式,分别是:

Command (命令模式)

Active Object (主动对象模式)

Template Method (模板方法模式)

Strategy (策略模式)

Facade(外观模式)

Mediator (中介者模式)

Singleton (单例模式)

Monostate (单态模式)

Null Object (空对象模式)

下面分别就我做了了解的模式进行介绍,分别是:

Command (命令模式)

Template Method (模板方法模式)

Strategy (策略模式)

Facade(外观模式)

Singleton (单例模式)

Command (命令模式)

我认为命令模式的主要作用在于两点:

1、解耦命令调用者(Invoker)和命令执行者(Receiver),让他们独立的变化

2、对需要重复使用的功能进行封装,以便实现一次书写,多次使用

命令调用者(Invoker)使用 Command 接口来调用 Receiver 来处理任务,而 Receiver 通过被 Command 接口的实现类调用,来完成任务

这样的话,Invoker 和 Receiver 可以独立地变化

且当有日志等系统性的功能需要实现的时候,可以直接在 Invoker 中加入相关代码,而不用每次调用命令的时候,都在 Client 中实现同样的代码

整个调用链:Client → Invoker(命令调用者,也是封装变化的地方) → Command ← ConcreteCommand(实现 Command 接口) ← Receiver

Template Method (模板方法模式)

我认为的要点:

1、使用抽象类封装算法(这里的算法指控制整个流程的代码)

2、将流程中每一步,交由具体的类去实现

调用链

abstract base class ← implement class

abstract base class 中定义了包含算法的实际(非抽象)方法,定义了流程中每一步的抽象方法

implement class 继承 abstract base class,实现了其中的抽象方法

这样,算法就可以被复用了

但是,有个缺点,那就是耦合性较高,要使用算法的话,必须继承抽象基类(abstract base class)

于是,就有了策略模式,对其进行改进

Strategy (策略模式)

使用模板方法模式时,为了实现算法的复用,必须要继承包含算法的抽象基类,耦合性较高

对此,策略模式使用了另一种方式实现算法的复用

即,将抽象的流程方法从抽象基类(abstract base class)中分离出去,分离到一个接口(interface)中

这样,抽象基类,就变成了只包含非抽象方法的非抽象基类(base class),而对于要复用算法的类而言,它只需要实现定义了那些抽象流程方法的接口即可

在使用时,客户端伪代码如下:

// 创建基类实例(利用带参的构造方法传入具体的实现类)

// 使用基类实例,调用包含算法代码的方法

这样,由于使用了接口隔离了算法和具体的实现代码

要使用某个算法的时候,就不用继承包含该算法的类了

而且,不仅算法可以复用,连具体的实现代码都可以复用(同类型的算法,使用同一份实现代码),即,在客户端代码中,创建的基类可以变,传入的实现类也可以变

Template Method (模板方法模式) 和 Strategy (策略模式) 的比较

以下是我个人的一些联想和思考,不一定正确

联想到,学习多线程的时候,两种创建线程的方式,是不是分别对应着模板方法模式和策略模式呢?
每次到最后,都是用 Thread 类的 start() 方法,那么,是不是 start() 方法里封装的就是算法呢?
注:Thread 里面,run() 方法应该不是封装算法的(这点跟书(指《敏捷软件开发》)上不同,书上使用 run() 方法封装算法的。)
书中的 run() 方法对应着 Thread 类里面的 start() 方法,然后 init()、idle()、cleanup() 对应的是 Thread 类里面的 run() 方法
在策略模式中,
ApplicationRunner 对应着 Thread
Application 对应着 Runnable
FtocStrategy 对应着某个具体的类
然后,
书中有个写法容易误导人,即
将最终的调用的代码,放在了 FtocStrategy  类中
其实应该放在另外的类中
因为,实际上是 ApplicationRunner  调用 FtocStrategy
而书中的写法,很容易让人以为是 FtocStrategy 调用的 ApplicationRunner
虽然,实际上是 FtocStrategy 需要使用 ApplicationRunner 中封装的算法
但是,结合依赖倒置原则,ApplicationRunner  应该是调用方,而 FtocStrategy 是被调用方
综上
从对象调用关系来看,ApplicationRunner 调用 FtocStrategy
从算法依赖关系来看,FtocStrategy 依赖了 ApplicationRunner  封装的算法
在模板方法模式中,ApplicationRunner 被继承,它的子类复制了它的代码(延用了它的算法),实现功能
在策略模式中,ApplicationRunner  将算法和具体实现方法分离,它主动去调用实现了这些实现方法的对象,利用他们完成功能
从算法复用上看,ApplicationRunner 中的算法在两种模式中,同样被复用了
从调用关系上看,相对于模板方法模式,在策略模式中,ApplicationRunner 化被动为主动

模板方法模式不符合 DIP,而策略模式符合 DIP

Facade(外观模式)

个人理解:

将一套复杂的逻辑,封装起来,只将需要关注的部分暴露给调用者

站在调用者的角度,那一套复杂的逻辑是不可见(也是不需要看见)的

调用者通过调用封装的那一个接口去调用它背后的一套复杂逻辑

感觉 JDBC 就是使用了这一模式,但是查了一下,发现 JDBC 主要使用的是桥接模式,现在对这个模式不了解,以后再查查

Singleton (单例模式)

类和示例通常是一对多的关系

但是

对于某些特殊的类,它们只允许有一个实例,比如,工厂对象、管理器对象

如果这些类有多个实例,会引发严重的逻辑错误

此时,就需要用到单例模式

实现单例模式有三个要点:

1、私有化构造函数

2、一个私有的私立变量

3、公开、静态的得到实例的方法(getInstance)

这样,外部就只能通过 getInstance 方法才能获取实例那个唯一的实例

猜你喜欢

转载自www.cnblogs.com/stone94/p/10633197.html
今日推荐