Android中的设计模式-模板方法模式

“浓眉大眼好干部,尖嘴猴腮狗特务,好人机枪打不死,坏蛋一枪就玩完!”,拍摄革命题材电影是有套路(模板)的,每当共产党员中枪了,要牺牲在战友怀中的时候,我们知道此时该有经典场景了:有的电影是“部队和群众都安全转移了吗?”,有的电影是“这是我的党费”,。。。不管哪种形式,用在这个场景肯定合适,然后就安详地闭上了双眼。

这就是模板方法模式在电影中的应用,它是属于行为型:

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

下面是它的结构类图。
这里写图片描述
- 抽象类(AbstractClass):定义要具体类实现的一些抽象方法。这些方法是一个完整操作中的基本步骤。在抽象类中,一般还会实现一个目标方法,该方法定义了整个操作的框架,即按特定流程调用每个基本步骤,以实现整个操作。
- 具体类(ConcreteClass):是抽象类的派生类,实现抽象类定义的抽象方法,一般在整个操作流程中融入自己的行为。

这也是一个非常简单的模式,简单的不能再简单了,它实际上体现了面向对象编程中的对象继承的典型应用。如果这个模式用一个关键词表示的话,我认为是继承,从结构图中也能看到,就是定义一个基类,然后派生出一个子类来继承它。

当然,该模式还是有自己的独特之处,它在基类中定义了算法的骨架,也就是模板方法(template method),同时定义了钩子方法(hook method)的抽象定义,并且在模板方法中要调用钩子方法。在实现时,由应用程序定义一个派生类并覆写这个钩子方法。模板方法要用到钩子方法,但是具体的钩子方法实现由子类来决定,通俗的讲,相当于在基类中事先挖好了坑,这些坑让子类来填上。

模板方法是不变的,而钩子方法是变化的。为了保持模板方法的不变,防止在子类中重写模板方法,比如在Java中,要用final来修饰模板方法。基类提供了模板,是不变的,子类按照模板的要求实现就行了,称之为模板方法模式还是恰如其分的。

那么,我们平时在面向对象编程实践中,找出对象的通用部分代码,并把它抽取出来放到基类中,这样能提高代码的复用性,那么这算是模板模式吗?模板模式侧重的是“定义一个算法的骨架,而将一些步骤延迟到子类中”,即:基类中的通用代码,肯定要用到一些具体方法,这些方法留到具体子类中去实现,从而来实现具体的业务逻辑。我们平时使用的继承只是简单的复用基类中的通用方法,这些通用代码和其它方法可能没有调用关系,它们互相独立。再者,模板子类实现的钩子方法被调用的地方已经被基类提前设置好了,创建对象后一般不会有别的对象来主动调用这些钩子方法(即正向依赖),只由基类在预定位置调用它们(即反向依赖),这就是经常所说的IOC-反向控制。

模板方法模式的职责是定义一个算法骨架,符合单一职责原则;具体实现依赖于钩子方法,符合依赖倒置原则;基类不关心具体类对钩子方法的实现,只是按照接口约定和预定流程调用就行,符合迪米特法则;当扩展功能时,定义一个新的子类就行了,接口没有变化,符合开关原则;基于继承实现,里氏替换原则更是不必说了。

模板方法模式是设计框架framework时,最经常使用的一种模式,即IOC。框架定义了一个通用的业务处理流程,来解决某一类业务逻辑,但是使用框架的应用程序往往是具体的,框架事先并不知道要处理什么样的具体业务,只好把一些与具体业务相关的方法抽象出来,即钩子方法,具体问题具体分析,留给使用框架的应用层来实现,从而让框架按照自己预定的流程来执行应用层的逻辑。基类定义了钩子方法,子类来实现钩子方法,基类使用钩子方法来完成具体业务,这是“面向接口编程”;应用层无论怎样实现钩子方法,都不用修改framework层的代码,这体现了该模式“封装变化”的一面。

策略模式相比,它们都提供了算法,策略模式侧重于基类抽象出算法接口,整个算法都是子类来实现,不同的子类有不同的算法逻辑,也就是对象的多态机制;而模板方法模式侧重于基类提供算法的基本骨架,而算法一些关键步骤由子类实现,也就是子类只实现了部分算法,一个是改变整个算法,另一个是改变部分算法。

Android就使用了大量的模板模式,比如,Activity、Fragment等有自己固定的生命周期,它按照Android自己设计的状态进行流转,但是在那个状态需要做什么事情,是与具体的应用有关。因此Activity、Fragment就定义了许多钩子方法,如onStart()/onResume(),onStop()…等等,应用要想处理自己的业务,就继承Activity或者Fragment,并重写这些方法,非常简单。

显然,模板方法模式的基础是我们面向对象编程的最基本的技能:继承、重写,例子比比皆是,不再举例了。Android中的Activity、Service、View、Fragment等都是模板方法模式的体现,相信大家都深有体会。

猜你喜欢

转载自blog.csdn.net/moter/article/details/80322235