Template Method 模版方法
重构关键技法
- 静态到动态
- 早绑定到晚绑定
- 继承到组合
- 编译时依赖到运行时依赖
- 紧耦合到松耦合
“组件协作”模式
现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
- 典型模式
Template Method
Strategy
Observer/Event
Template Method
动机
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现。
例子1:银行业务办理流程在银行办理业务时,一般都包含几个基本固定步骤:取号排队->办理具体业务->对银行工作人员进行评分。取号取号排队和对银行工作人员进行评分业务逻辑是一样的。但是办理具体业务是个不相同的,具体业务可能取款、存款或者转账。
如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?
软件设计流程
-
结构化
- 面向对象
早绑定与晚绑定
模式定义
定义一个操作中的算法的骨架(稳定),而将一些步骤(变化)延迟到子类中。 T模板方法使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
解决方法:
- 1)模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。
- 2)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。
结构
要点总结
- T模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
- 除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是T模式的典型应用。
- 在具体实现方面,被T模式调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置prtected方法
策略模式(选择上的变化)
动机
- 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有些时候支持不使用的算法也是一个性能负担
- 如何在运行时根据需要需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
模式定义(枚举类型,switch等)
定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换(变化)。本模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)。
适用性
当存在以下情况时使用Strategy模式
- 许多相关的类仅仅是行为有异。 “策略”提供了一种用多个行为中的一个行为来配置一个类的方法。即一个系统需要动态地在几种算法中选择一种。
- 需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间 /时间权衡的算法。当这些变体实现为一个算法的类层次时 ,可以使用策略模式。
- 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
- 一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
结构
模式的组成
- 环境类(Context):用一个ConcreteStrategy对象来配置。维护一个对Strategy对象的引用。可定义一个接口来让Strategy访问它的数据。
- 抽象策略类(Strategy):定义所有支持的算法的公共接口。 Context使用这个接口来调用某ConcreteStrategy定义的算法。
- 具体策略类(ConcreteStrategy):以Strategy接口实现某具体算法
要点总结
- Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。
- Strategy模式提供了用条件判断语句以外 的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
- 如果Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。
5.观察者模式
textwatch 如何实现
不会耦合具体的观察者
观察者自己来决定是否需要订阅通知,目标对象对此一无所知