1. 模板方法模式概述
在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都包含点单、吃东西、买单等几个步骤,通常情况下这几个步骤的次序是:点单 --> 吃东西 --> 买单。在这三个步骤中,点单和买单大同小异,最大的区别在于第二步——吃什么?吃面条和吃满汉全席可大不相同,如图1所示:
图1 请客吃饭示意图
在软件开发中,有时也会遇到类似的情况,某个方法的实现需要多个步骤(类似“请客”),其中有些步骤是固定的(类似“点单”和“买单”),而有些步骤并不固定,存在可变性(类似“吃东西”)。为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。在模板方法模式中,可以将相同的代码放在父类中,例如将模板方法“请客”以及基本方法“点单”和“买单”的实现放在父类中,而对于基本方法“吃东西”,在父类中只做一个声明,将其具体实现放在不同的子类中,在一个子类中提供“吃面条”的实现,而另一个子类提供“吃满汉全席”的实现。通过使用模板方法模式,一方面提高了代码的复用性,另一方面还可以利用面向对象的多态性,在运行时选择一种具体子类,实现完整的“请客”方法,提高系统的灵活性和可扩展性。
模板方法模式定义如下:
模板方法模式:定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
Template Method Pattern: Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure. |
模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式。
模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而通过其子类来覆盖某些步骤,从而使得相同的算法框架可以有不同的执行结果。模板方法模式提供了一个模板方法来定义算法框架,而某些具体步骤的实现可以在其子类中完成。
2. 模板方法模式结构与实现
2.1 模式结构
模板方法模式结构比较简单,其核心是抽象类和其中的模板方法的设计,其结构如图2所示:
图2 模板方法模式结构图
由图2可知,模板方法模式包含如下两个角色:
(1) AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
(2) ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。
2.2 模式实现
在实现模板方法模式时,开发抽象类的软件设计师和开发具体子类的软件设计师之间可以进行协作。一个设计师负责给出一个算法的轮廓和框架,另一些设计师则负责给出这个算法的各个逻辑步骤。实现这些具体逻辑步骤的方法即为基本方法,而将这些基本方法汇总起来的方法即为模板方法,模板方法模式的名字也因此而来。下面将详细介绍模板方法和基本方法:
1. 模板方法
一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类,而不是接口。
2. 基本方法
基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
(1) 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。在C#语言里一个抽象方法以abstract关键字标识。
(2) 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
(3) 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。
在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是bool类型的,这类方法名一般为IsXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行,如下代码片段所示:
- ……
- //模板方法
- public void TemplateMethod()
- {
- Open();
- Display();
- //通过钩子方法来确定某步骤是否执行
- if (IsPrint())
- {
- Print();
- }
- }
- //钩子方法
- public bool IsPrint()
- {
- return true;
- }
- ……
在代码中IsPrint()方法即是钩子方法,它可以决定Print()方法是否执行,一般情况下,钩子方法的返回值为true,如果不希望某方法执行,可以在其子类中覆盖钩子方法,将其返回值改为false即可,这种类型的钩子方法可以控制方法的执行,对一个算法进行约束。
还有一类钩子方法就是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法,与抽象方法相比,这类钩子方法的好处在于子类如果没有覆盖父类中定义的钩子方法,编译可以正常通过,但是如果没有覆盖父类中声明的抽象方法,编译将报错。
在模板方法模式中,抽象类的典型代码如下:
- abstract class AbstractClass
- {
- //模板方法
- public void TemplateMethod()
- {
- PrimitiveOperation1();
- PrimitiveOperation2();
- PrimitiveOperation3();
- }
- //基本方法—具体方法
- public void PrimitiveOperation1()
- {
- //实现代码
- }
- //基本方法—抽象方法
- public abstract void PrimitiveOperation2();
- //基本方法—钩子方法
- public virtual void PrimitiveOperation3()
- { }
- }
在抽象类中,模板方法TemplateMethod()定义了算法的框架,在模板方法中调用基本方法以实现完整的算法,每一个基本方法如PrimitiveOperation1()、PrimitiveOperation2()等均实现了算法的一部分,对于所有子类都相同的基本方法可在父类提供具体实现,例如PrimitiveOperation1(),否则在父类声明为抽象方法或钩子方法,由不同的子类提供不同的实现,例如PrimitiveOperation2()和PrimitiveOperation3()。
可在抽象类的子类中提供抽象步骤的实现,也可覆盖父类中已经实现的具体方法,具体子类的典型代码如下:
- class ConcreteClass : AbstractClass
- {
- public override void PrimitiveOperation2()
- {
- //实现代码
- }
- public override void PrimitiveOperation3()
- {
- //实现代码
- }
- }
在模板方法模式中,由于面向对象的多态性,子类对象在运行时将覆盖父类对象,子类中定义的方法也将覆盖父类中定义的方法,因此程序在运行时,具体子类的基本方法将覆盖父类中定义的基本方法,子类的钩子方法也将覆盖父类的钩子方法,从而可以通过在子类中实现的钩子方法对父类方法的执行进行约束,实现子类对父类行为的反向控制。
【作者:刘伟 http://blog.csdn.net/lovelion】
ps:copy过来仅仅为了阅读标记,无任何其他目的。
相关推荐
在现实生活中,很多事情都包含几个实现步骤,例如请客吃饭,无论吃什么,一般都...为了提高代码的复用性和系统的灵活性,可以使用一种称之为模板方法模式的设计模式来对这类情况进行设计,在模板方法模式中,将实现功能
(1) AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的
10. **设计模式**:C++深度解析教程可能还会涵盖常见的设计模式,如工厂模式、单例模式、观察者模式等,这些都是解决特定编程问题的成熟解决方案,有助于提高代码的可维护性和可扩展性。 通过学习《C++深度解析》...
《设计模式解析》这一标题暗示了书籍将深度探讨各种设计模式,包括其原理、应用及背后的思维逻辑,帮助读者掌握并灵活运用这些模式来优化软件设计。 #### 描述解析:设计模式的入门与精通之路 描述中提到设计模式...
- **Iterator模式**:提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。 - **Interpreter模式**:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释...
在本文中,我们将深入探讨如何使用JavaScript来实现自定义模板树解析,这是一项核心技能,对于构建复杂的前端界面和数据驱动的应用至关重要。 自定义模板树解析涉及到将HTML字符串或模板转换为可操作的数据结构,这...
### PHP框架深度解析 #### 一、什么是PHP框架? PHP框架是一种软件结构,它为开发者提供了构建Web应用程序的基础模板和工具集。通过使用框架,开发者可以避免重复编写常见功能的代码,例如用户认证、数据库交互、...
模板匹配是模式识别的一种基础方法,主要解决的是如何在图像或其他数据中找到特定模式的位置。它通过比较模板图像与目标图像的局部区域,评估它们的相似度,以确定模板是否存在以及其在图像中的位置。模板匹配的用途...
总的来说,"深度解析C++对象模型"涵盖了C++语言中的核心概念,如类、对象、继承、多态、内存管理和模板,这些都是理解和编写高效C++代码的基石。通过深入学习和实践,开发者可以更好地掌握C++的精髓,编写出更加健壮...
算法的封装与切换——策略模式(四) 模板方法模式-Template Method Pattern 模板方法模式深度解析(一) 模板方法模式深度解析(二) 模板方法模式深度解析(三) 访问者模式-Visitor Pattern 操作复杂对象结构——...
《Android 源码设计模式解析与实战》是一本深入探讨Android系统源码中设计模式应用的专业书籍。这本书全面解析了Android系统中的设计模式,并结合实际案例,为开发者提供了丰富的实战经验。书中涵盖的设计模式是软件...
下面将详细解析这一方法的原理、应用及重要性。 1. **单帧调制模板**:传统的深度信息获取通常依赖于多帧数据的对比和计算,而单帧调制模板技术则改变了这一模式。这种方法通过在光源上使用特定的调制模板,如光栅...
通过熟练掌握这些模板,用户可以编写出强大的脚本,实现对二进制文件的深度解析和处理。 总的来说,010 Editor Templates是010 Editor的精华所在,它提供了丰富的预设工具,帮助用户轻松应对各种二进制文件挑战。...
模板方法模式提供了一种flexible的方式来实现对象的行为,而普通的实现类继承抽象类方式则需要固定地继承抽象类。 7. 是比较和分析适配器模式和桥接模式之间的共性和差异性? 适配器模式和桥接模式都是结构型模式...
《商业模式画布:商务PPT模板的深度解析与应用》 在商业世界中,有效的沟通是成功的关键。而“商业模式画布”作为一种直观且实用的工具,已经成为了商业策略制定和展示的重要方式。本篇文章将深入探讨商业模式画布...
这些实现都基于模板模式,使用 Resource 接口来抽象 Bean 定义数据,并将 Xml 定义文件的解析委托给 XmlBeanDefinitionReader。 二、BeanFactory 接口 BeanFactory 接口是 IOC 容器的基本接口,它定义了 IOC 容器...
它通过将Model(模型)、View(视图)和Controller(控制器)分离,实现了MVC设计模式,提高了代码的组织性和可测试性。在本课中,我们将深入解析Spring MVC的工作原理。 首先,我们来看看Spring MVC的核心功能特性...