Template Method Pattern

模板模式 (Template Method Pattern) 一、什么是模板 既然是模板设计思维,那首先要探索一下到底何为模板,搞清楚现实中模板是啥样的,才能进一步把模板抽象化。 一提到模板,我最先想到的是PowerPoint,没错,就是让人头疼的PPT,马上要述职汇报了,PPT确实让人头大~ 人事的小姐姐已经把汇报的ppt模板发给我们了,我看了下汇报流程,如下: 不管你是张三、李四还是王五,都要按照这4个方... 阅读详情

一、 模板方法(Template Method)模式

准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模版方法模式的用意。

很多人可能没有想到,模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模式的结构和用法也是面向对象设计的核心。

模版方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本法方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字就是从此而来。


二、 模版方法模式的结构

模版方法模式的静态结构如下图所示。

 

这里涉及到两个角色:

  • 抽象模版(AbstractClass)角色有如下的责任:

定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。

定义并实现了一个模版方法。这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。

  • 具体模版(ConcreteClass)角色有如下的责任:

实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。

每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。


三、 模板方法模式的示意性代码

// Template Method pattern -- Structural example  
using System;

// "AbstractClass"
abstract class AbstractClass
{
  
// Methods
  abstract public void PrimitiveOperation1();
  
abstract public void PrimitiveOperation2();

  
// The Template method
  public void TemplateMethod()
  
{
    Console.WriteLine(
"In AbstractClass.TemplateMethod()");
    PrimitiveOperation1();
    PrimitiveOperation2();
  }

}


// "ConcreteClass"
class ConcreteClass : AbstractClass
{
  
// Methods
  public override void PrimitiveOperation1()
  
{
    Console.WriteLine(
"Called ConcreteClass.PrimitiveOperation1()");
  }


  
public override void PrimitiveOperation2()
  
{
    Console.WriteLine(
"Called ConcreteClass.PrimitiveOperation2()");
  }

}


/// <summary>
/// Client test
/// </summary>

public class Client
{
  
public static void Main( string[] args )
  
{
    
// Create instance and call template method
    ConcreteClass c = new ConcreteClass();
    c.TemplateMethod();
  }

}


四、 继承作为复用的工具

使用继承作为复用的手段必须慎重,C#语言的设计师对使用继承作为复用的工具有着不同层次上的认识。

不知其一

首先,初学C#的程序员可能不知道什么是继承,或者认为"继承"是高深的工具。那时候,大部分的功能复用都是通过委派进行的。

知其一、不知其二

然后慢慢地,他们发现在C#语言里实现继承并不困难,并且初步认识到继承可以使子类一下子得到基类的行为。这时他们就会跃跃欲试了,试图使用继承作为功能复用的主要工具,并把原来应当使用委派的地方,改为使用继承,这时继承就有被滥用的危险。

知其二

很多面向对象的设计专家从1986年就开始警告继承关系被滥用的可能。有一些面向对象的编程语言,如SELF语言,甚至将类的继承关系从语言的功能中取消掉,改为完全使用委派。

其他的设计师虽然不提倡彻底取消继承,但无一例外地鼓励在设计中尽可能使甩委派关系代替继承关系。比如在【GOF95】一书中,状态模式、策略模式、装饰模式、桥梁模式以及抽象工厂模式均是将依赖于继承的实现转换为基于对象的组合和聚合的实现,这些模式的要点就是使用委派关系代替继承关系。

知其三

是不是继承就根本不该使用呢?事实上对数据的抽象化、继承、封装和多态性并称C#和其他绝大多数的面向对象语言的几项最重要的特性。继承不应当被滥用,并不意味着继承根本就不该使用。因为继承容易被滥用就彻底抛弃继承,无异于因噎废食。

继承使得类型的等级结构易于理解、维护和扩展,而类型的等级结构非常适合于抽象化的设计、实现和复用。尽管【GOF95】所给出的设计模式基本上没有太多基于继承的模式,很多模式都是用继承的办法定义、实现接口的。多数的设计模式都描写一个以抽象类作为基类,以具体类作为实现的等级结构,比如适配器模式、合成模式、桥梁模式、状态模式等。

模版方法模式则更进了一步:此模式鼓励恰当地使用继承。此模式可以用来改写一些拥有相同功能的相关的类,将可复用的一般性的行为代码移到基类里面,而把特殊化的行为代码移到子类里面。

因此,熟悉模版方法模式便成为一个重新学习继承的好地方。


五、 一个实际应用模板方法的例子

下面的例子演示了数据库访问的模板方法。实际应用时,请确保C盘根目录下有nwind.mdb这个Access数据库(可以从Office的安装目录下找到。中文版用户的请注意字段名可能有所不同)。

// Template Method pattern -- Real World example  
using System;
using System.Data;
using System.Data.OleDb;

// "AbstractClass"
abstract class DataObject
{
  
// Methods
  abstract public void Connect();
  
abstract public void Select();
  
abstract public void Process();
  
abstract public void Disconnect();

  
// The "Template Method"
  public void Run()
  
{
    Connect();
    Select();
    Process();
    Disconnect();
  }

}


// "ConcreteClass"
class CustomerDataObject : DataObject
{
  
private string connectionString =
    
"provider=Microsoft.JET.OLEDB.4.0; "
    
+ "data source=c:\\nwind.mdb";
  
private string commandString;
  
private DataSet dataSet;
 
  
// Methods
  public override void Connect( )
  
{
    
// Nothing to do
  }


  
public override void Select( )
  
{
    commandString 
= "select CompanyName from Customers";
    OleDbDataAdapter dataAdapter 
= new OleDbDataAdapter(
      commandString, connectionString );
    dataSet 
= new DataSet();
    dataAdapter.Fill( dataSet, 
"Customers" );
  }


  
public override void Process()
  
{
    DataTable dataTable 
= dataSet.Tables["Customers"];
    
foreach( DataRow dataRow in dataTable.Rows )
      Console.WriteLine( dataRow[ 
"CompanyName" ] );
  }


  
public override void Disconnect()
  
{
    
// Nothing to do
  }

}


/// <summary>
///  TemplateMethodApp test
/// </summary>

public class TemplateMethodApp
{
  
public static void Main( string[] args )
  
{
    CustomerDataObject c 
= new CustomerDataObject( );
    c.Run();
  }

}

 

六、 模版方法模式中的方法

模版方法中的方法可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。

模版方法

一个模版方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模版方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来。

基本方法

基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在C#语言里一个抽象方法以abstract关键字标示出来。

具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。在C#语言里面,一个具体方法没有abstract关键字。

钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。(Visual FoxPro中项目向导建立的项目会使用一个AppHook类实现监视项目成员变化,调整系统结构的工作。)钩子方法的名字通常以do开始。


七、 重构的原则

在对一个继承的等级结构做重构时,一个应当遵从的原则便是将行为尽量移动到结构的高端,而将状态尽量移动到结构的低端。

1995年,Auer曾在文献【AUER95】中指出:

  1. 应当根据行为而不是状态定义一个类。也就是说,一个类的实现首先建立在行为的基础之上,而不是建立在状态的基础之上。
  2. 在实现行为时,是用抽象状态而不是用具体状态。如果一个行为涉及到对象的状态时,使用间接的引用而不是直接的引用。换言之,应当使用取值方法而不是直接引用属性。
  3. 给操作划分层次。一个类的行为应当放到一个小组核心方法(Kernel Methods)里面,这些方法可以很方便地在子类中加以置换。
  4.  将状态属性的确认推迟到子类中。不要在抽象类中过早地声明属性变量,应将它们尽量地推迟到子类中去声明。在抽象超类中,如果需要状态属性的话,可以调用抽象的取值方法,而将抽象的取值方法的实现放到具体子类中。

如果能够遵从这样的原则,那么就可以在等级结构中将接口与实现分隔开来,将抽象与具体分割开来,从而保证代码可以最大限度地被复用。这个过程实际上是将设计师引导到模版方法模式上去。

实战指南:从零搭建ROS2 + Cartographer 2D激光SLAM系统 本文详细介绍了如何从零开始搭建ROS2与Cartographer结合的2D激光SLAM系统,涵盖环境准备、激光雷达驱动配置、Cartographer安装与参数调优等关键步骤。通过实战案例和常见问题解决方案,帮助开发者快速掌握激光雷达建图技术,提升机器人自主导航能力。 阅读详情

相关推荐

创建动态代理对象bean,并动态注入到spring容器中

使用过Mybatis的同学,应该都知道,我们只需要编写mybatis对应的接口和mapper XML文件即可,并不需要手动编写mapper接口的实现。这里mybatis就用到了JDK动态代理,并且将生成的接口代理对象动态注入到Spring容器中。 这里涉及到几个问题。也许有同学会有疑问,我们直接编写好类,加入@Component等注解不是可以注入了吗?或者在配置类(@Configuration)...

lichuangcsdn的博客 3万+

模板方法模式(模板方法设计模式)详解

前言 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。 例如,去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。 这样的例子在生活中还有很多,例如,一个人每天会起床、吃饭

weixin_41979002的博客 2954

DVWA靶场实战:从搭建到渗透测试的完整指南

本文详细介绍了DVWA靶场的搭建与渗透测试全流程,涵盖LAMP环境搭建、Docker部署及集成环境安装三种方式。通过SQL注入、文件上传漏洞等实战案例,帮助读者掌握Web安全测试技巧,并提供防御方案与进阶调优建议,是网络安全学习的实用指南。

weixin_28312391的博客 488

Java设计模式—模板方法模式

  (尊重劳动成果,转载请注明出处:https://blog.youkuaiyun.com/qq_25827845/article/details/51868973冷血之心的博客)   目录 1、定义: 2、通用类图如下: 具体模板: 3、通用代码如下: 抽象模板类: 具体模板类: 场景类: 优点: 缺点: 总结: 模板方法模式仅仅使用了Java的继承机制,但它是一个应用非常广泛的...

冷血之心的博客 1万+

腾讯2020 unreal虚幻面试题

解析一下,腾讯的unreal客户端面试题: 1.lua性能优化的方向 申请的内存,是造成卡顿的原因之一,在C++与lua交互中,如果参数或者返回值有类变量,那么这个变量不会再交互的栈中存放数据,而会通过申请内存,再指定在交互,这样就造成卡顿,因此可以通过把C++的对象的每个参数分开单独传递,可以解决问题,当时我们游戏改完这个问题后,整体提升了2帧。 其实,主要是Tick循环中,减少与C++的交互,需要的数据不要每帧都去拿,其次,经常拿的一些数据(比方说主角信息),可以做一个lua缓存,...

qq_17347313的博客 1万+

蓝鸟四轴飞控系统C程序V3.0(基础版本)深度解读

2. 解析遥控通道数据(油门 / 横滚 / 俯仰 / 偏航),转换为标准化值(-1000~+1000);3. 封装PID初始化(PID_Init,配置KP/KI/KD、输出限幅、积分限幅);,包含姿态角(Attitude_Data.Roll/Pitch/Yaw)、角速度(Gyro_Data.X/Y/Z)、遥控值(RC_Data[0~5])、电池电压(Bat_Volt)、电机PWM值(Motor_PWM[0~3])、系统状态(Sys_State),校验和通过Check_Sum()函数计算;

搏博的专栏 344

【设计模式——学习笔记】23种设计模式——模板方法模式Template Method(原理讲解+应用场景介绍+案例介绍+Java代码实现)

讲解模板方法模式的思想,介绍其常见的应用场景,举例说明其实现方式

我只管埋头前行,剩下的交给时间。 4711

(五)深入理解蓝牙BLE之“Beacon包格式详解”

蓝牙Beacon格式详解 本文重点在结合Bluetooth官网spec和几个例子来使beacon帧格式更加容易被理解。 广播帧格式: 首先beacon是蓝牙BLE广播包的一种,蓝牙广播帧格式如下: PS:其实BLE数据帧除了报头字段和数据字段定义与广播帧不同之外,前导/接入地址/长度/校验格式均相同。 广播帧数据字段格式: 数据字段最长为37个字节:6个字节的广播设备地址 + 31个字节广播数据。 广播数据的格式如下:AD Structure1 +AD Structure2 + .....

1万+

设计模式-模板方法模式(Template Method)

模板方法模式,也被称为模板模式,是一种行为型设计模式。它在一个抽象类中公开定义了执行其方法的模板,规定了算法的骨架。其主要特点是将一些步骤延迟到子类中,这些子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式主要解决了一些通用的方法在每一个子类都重新写了这一问题,其主要目的是将这些通用算法抽象出来。通过使用模板方法模式,子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。

miaoyl的博客 3195

LVGL 实战:倒计时翻页钟

环境:LVGL 9.x + PC 模拟器。每个数字做成上下两半的卡片,秒变时用绕中缝翻页:上半旧页折叠下去、下半新页展开上来,配合阴影遮罩做出立体感。从 02:00 倒计时到 0,闪一下再重置。界面文案用英文(默认字体无中文)。

摸鱼专家 213

对接金蝶云星空调用即时库存信息查询API(附JAVA实现)

这篇文章教你如何对接金蝶API并且使用JAVA调用金蝶云星空的即时库存查询API

实用的博客 2608

Java设计模式之模板方法(Template Method)模式

模板方法(Template Method)设计模式为子类定义算法的骨架,而将算法中某些步骤的实现延迟到子类中。这使得子类可以在修改算法的结构上有自己的变化。

小虎哥的技术博客 1943

【WorkBuddy专栏32】从「分文件夹」到「组队打仗」——WorkBuddy v5.0项目模式深度拆解

【WorkBuddy专栏32】从「分文件夹」到「组队打仗」——WorkBuddy v5.0项目模式深度拆解

AI人人懂 297

The first glance of Template Method Pattern

上次看团队的技术讨论Blog,了解到了大家说Template Method Pattern是常用的设计模式之一,所以今天可花了点时间看了一下,起初一看,感觉没什么,太简单了,不就是继承吗?父类给个模板,子类相应的实现不就可以了吗?后来稍加注意了一下,感觉自己的理解只停留在Template上,却没有关注Method,实际上在父类中要有一个模板方法(template method),这个方法可...

weixin_30689307的博客 88

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

java——模版方法模式( Template Method pattern)

7.模版方法模式( Template Method pattern)

超人迪X 151

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

template method pattern

//DataViewer.cs using System; namespace TemplateMethodSample { abstract class DataViewer { //抽象方法:获取数据 public abstract void GetData(); ...

165

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Design Pattern Template Method C

Design Pattern Template Method C

yffhhffv的博客 194

Design Pattern: Template Method 模式

学习是分享和合作式的! 转载请注明出处:http://blog.youkuaiyun.com/wdzxl198/article/details/9223275; 文章摘自: http://www.riabook.cn/doc/designpattern/; 不要将设计模式想得高不可攀,好像高手才会使用的东西,事实上如果您在下手程式之前,能稍稍对程式作个分析规划,或多或少都会用到一些模式了,模式不

Atlas2013的专栏 979

【C++设计模式之Template Method Pattern】

模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的骨架,并将某些步骤的具体实现延迟到子类中。该模式的核心思想是“不变流程,可变细节”,通过将公共逻辑封装在基类中,允许子类在不改变算法流程的前提下重写特定步骤。这种模式避免了代码重复,并明确了哪些步骤可以扩展。

weixin_43488529的博客 679

Strategy Pattern /Template Method Pattern

现在就来说说策略模式[Stragegy Pattern]/和模板方法模式[Template Method Pattern]: 几个原则:Program to an interface, not an implementation [针对接口编程,而不要针对实现编程] Favor object [aggregation] over class inheritance [优

旅途 871

模板模式(Template Method Pattern)

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。 UML Class Diagram 实现代码 package engineering.papers; /** * Created by DELL * Date: 2019/9/28. * Ti...

qq_21344887的博客 515

[Design] Template Method Pattern

  行为模式主要是责任和算法的抽象化。行为模式不仅仅是关于类和对象的,而且是关于它们之间的相互作用的。  行为模式分为类的行为模式和对象的行为模式两种。类的行为模式 类的行为模式使用继承关系在几个类之间分配行为。对象的行为模式 对象的行为模式则使用对象的聚合来分配行为。------------------------------------------------------...

diangang3082的博客 90
上一篇: Spring技术内幕1 Spring的设计理念和整理架构
下一篇: Spring技术内幕2Spring Framework的核心:IoC容器的实现
partner4java
博客等级 码龄17年 481粉丝 183原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值