小谈设计模式(11)—模板方法模式 专栏介绍 主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。 角色分类 抽象类(Abstract Class) 抽象类定义了一个模板方法,该方法包含了算法的框架,以及一系列基本方法的调用顺序。 抽象方法(Abstract Method) 抽象方法是在抽象类中声明的方法,由具体子类实现。抽象方法是模板方法中的基本方法,用于完成算法的一部分。 具体方法(Concrete Method) 具体方法是在抽象类中已经实现的方法,可以在模板方法中直接调用。具体方法是模板方法中的基本方法,用于完成算法的一部分。 抽象类定义了一个模板方法,该方法包含了算法的框架,以及一系列基本方法的调用顺序。抽象类还可以定义抽象方法、具体方法和钩子方法,用于延迟具体实现或提供默认实现。
模板方法模式(Template Method Pattern)属行为型,在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中,使子类可以不改变算法结构即可重定义算法的某些特定步骤。 模版方法模式结构图: image.png AbstractClass:实现了模板方法,定义了算法骨架。 ConcreteClass:实现抽象类中的抽象方法,完成完整的算法。 2.模板方法模式简单实现 我们仍来举一个武侠的例子。 一个武侠要战斗的时候,也有一套固定的模式,那就是运行内功、开通经脉、准备武器和使用招式。 4.小结 (1)模板方法模式定义了算法的步骤,将这些步骤的实现延迟到了子类。 (2)模板方法模式为我们提供了一种代码复用的重要技巧。 (3)模板方法模式的抽象类可以定义抽象方法、具体方法和钩子方法。 ---- 参考文献 [1]设计模式(九)模版方法模式 [2]Head First 设计模式(中文版):275-311 [3]设计模式读书笔记—–模板方法模式
一、简介 1、模板方法模式定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 2、说白了模板方法模式就是将一些通用的步骤放在基类中,而将不同的环节放在子类中,以减少代码的重用。 5、所属类别:行为型 二、C++代码 1 // 模板方法模式.cpp : 定义控制台应用程序的入口点。 include "stdafx.h" 5 #include<iostream> 6 using namespace std; 7 8 class Shijuan 9 { 10 public: 11
定义### 在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 2、模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。 2、模板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。 3、在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。 不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。
模板方法模式是为这些情况设计的:整体算法的设计是一个抽象类,它有一系列抽象方法,代表算法中可被定制的步骤,同时这个类中包含了一些通用代码。 图1 使用模板方法模式描述申请贷款过程 CompanyLoanApplication 的checkIdentity 方法在Companies House 等注册公司数据库中查找相关信息。 图2 员工申请贷款是个人申请的一种特殊情况 使用Lambda 表达式和方法引用,我们能换个角度思考模板方法模式,实现方式也跟以前不一样 模板方法模式真正要做的是将一组方法调用按一定顺序组织起来。如果用函数接口表示函数,用Lambda 表达式或者方法引用实现这些接口,相比使用继承构建算法,就会得到极大的灵活性。 使用函数接口实现检查方法并没有排除继承的方式。我们可以显式地在这些类中使用Lambda 表达式或者方法引用。
模板方法模式 模板方法模式Template Method Pattern定义了如何执行某些算法的框架,一个抽象类公开定义了执行它的方法的方式或模板,其子类可以按需要重写方法实现,也可以调用将以抽象类中定义的方式进行 描述 模板方法模式是一种行为设计模式,用于定义操作中算法的程序框架,从而将某些步骤推迟到子类中,其可以重新定义算法的某些步骤,而无需更改算法的结构。 适用环境 有多个子类共有的方法,且逻辑相同。 重要的、复杂的方法,可以考虑作为模板方法。
今天咱们就来一起学习模板方法模式。 那么,什么是模板方法模式呢?在解决这个问题前,咱们先来看看模板。 将模板的思想发散到编程上,就是我们今天的主题了。 模板方法Gof的定义是:在一个方法里定义算法的骨架,将一些步骤延迟到其子类。 模板方法模式把我们不知道具体实现的步骤封装成抽象方法,提供一个按正确顺序调用它们的具体方法(这些具体方法统称为“模板方法”),这样构成一个抽象基类。 父类通过顶级逻辑,它通过定义并提供一个具体方法来实现,我们也称之为模板方法。通常这个模板方法才是外部对象最关心的方法。所以它必须是public的,才能被外部对象所调用。 注意:模板方法模式中,迫使子类实现的抽象方法应该声明为protected abstract。 6. 模板方法和其他模式的联系 各个模式之间都有联系,模板方法也不例外,她并不是孤立存在的。
一、概念 模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。 解析:模板方法模式用来创建一个算法的模板。什么是模板?模板就是一个方法。更具体地说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。 * 2、我们一般把模板方法定义成 final,不希望子类覆盖。 ,实现了抽象模板中定义为 abstract 的步骤方法,并可以自己选择是否重写钩子方法。 为防止子类改变模板方法中的算法,可以将模板方法声明为 final。 策略模式和模板方法模式都封装算法,但是策略模式使用的是组合,模板方法模式使用的是继承。 工厂方法是模板方法的一种特殊版本。
1.函数模板默认模板参数简介 函数模板与类模板在C++98一起被引入,因种种原因,类模板可以拥有默认模板参数,而函数模板不可以。从C++11开始,这个限制被解除了,即函数模板同样可以拥有默认模板参数。 static void _printTypeName() { cout<<"T="<<typeid().name()<<endl; } }; //函数<em>模板</em>的默认<em>模板</em>参数,C++<em>11</em>开始支持 2.函数<em>模板</em>默认<em>模板</em>参数的特点 函数<em>模板</em>默认<em>模板</em>参数的用法虽然与类<em>模板</em>默认<em>模板</em>参数和函数默认参数的用法类似,但是有一个显著的特点,即当函数<em>模板</em>拥有多个默认<em>模板</em>参数时,其出现的顺序可以任意,不需要连续出现在<em>模板</em>参数的最后面 ,而在C++<em>11</em>中,函数<em>模板</em>的默认<em>模板</em>参数出现的位置则比较灵活,可以出现在任意位置。 ---- 参考文献 [1]深入理解C++<em>11</em>[M].2.11<em>模板</em>函数的默认<em>模板</em>参数
模板方法模式(Template Method Pattern)详解 1. 定义 模板方法模式是一种行为型设计模式,定义一个操作中的算法骨架,将某些步骤的实现延迟到子类。 通过模板方法,子类可以在不改变算法结构的情况下重新定义算法的某些步骤。 通俗解释: 模板方法就像烹饪中的食谱,它定义了做菜的步骤(算法骨架),而每道菜的具体细节(比如调味方式)由厨师(子类)决定。 模板方法模式的优缺点 特性 模板方法模式 策略模式 优点 复用性高:提取通用逻辑,避免重复代码。扩展性强:子类只需实现定制化步骤。清晰明确:明确了算法的执行顺序,逻辑更清楚。 模板方法模式的组成 抽象类 定义算法的骨架(模板方法)和必要的抽象方法。 具体子类 实现抽象类中的具体步骤,定制行为。 模板方法模式的扩展 钩子方法(Hook Method) 模板方法模式中可以包含钩子方法,子类可以通过覆盖钩子方法来影响模板方法的行为,但不是必须实现的。这种方法进一步增强了模式的灵活性。 7.
《大化设计模式》中的中文定义:模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法可使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 模板方法模式的UML类图 模板方法模式的UML类图如下:(摘自《Head First Design Pattern AbstractClass是抽象类,定义并实现了一个模板方法。 模板方法一般是一个具体方法,而该方法的组成逻辑,可能推迟到子类中实现。ConcreteClass可以有任意多个,每个可以给出父类抽象逻辑的实现。 模板方法模式的用途 当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的从层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。 烧好开水 冲泡咖啡豆 将饮料导入杯中 添加糖牛奶 模板方法模式和策略模式以及工厂方法模式的对比 模板方法模式和工厂方法模式都是让具体的实现放在子类中,但是工厂方法属于创建型模式,它提供了一种创建复杂对象的最佳方式
void checkHardware(); /** * 载入操作系统 */ protected abstract void loadOS(); // 下面是模板方法 ,定义为final,子类不能覆盖此方法 /** * 启动计算机方法,步骤为开启电源、系统检查、加载系统、检查是否登录。 computer.startUp(); computer = new ComputerB(); computer.startUp(); } 3.总结: 模板方法模式用 也就是把某个固定的流程封装到一个final方法中,并且让子类能够定制这个流程中的某些或者所有步骤,这就要求父类提取公用的代码,提升代码的复用率,同时带来了更好的可扩展性。 2.缺点 增加代码阅读难度,会让用户觉得难以理解 4.android中的模板模式 http://blog.csdn.net/lxj1137800599/article/details/53705274
可见其实模板方法模式的类结构很简单。 image.png 我们根据上面所举的例子,来具体实现模板方法模式。 /** 12 * 模板方法1。 ),两个学生写出自己的答案(实现抽象行为): 1 package day_23_templateMethod; 2 3 /** 4 * 实现模板方法中所要调用的抽象方法。 ,我们给模板方法模式一个定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式属于行为类模式。 模板方法的组成 类图: 如图所示,模板方法模式主要由AbstractClass(抽象类)和ConcreteClass(具体子类)组成。 AbstractClass(抽象类):定义一个模板,亦称为算法的“骨架”,在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤 同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法 应用举例 模板方式是我们开发中 遇到的常用方法。例如,某日,程序员A拿到一个任务:给定一个整数数组,把数组中的数由小到大排序,然后把排序之后的结果打印出来。 new ConcreteSort(); s.showSortResult(a); } } 排序结果: 0 1 3 4 5 7 9 10 12 32 模板方法的应用场景
3.1消除重复代码 3.2实现泛化的delegate 4.总结 参考文献 1.概述 变参模板(variadic template)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0 可变模版参数和普通的模版参数语义是一致的,可以应用于函数和类,然而,函数模版不支持偏特化,所以可变参数函数模版和可变参数类模版展开参数包的方法有所不同,下面我们来分别看看他们参数包展开的方法。 ,比如C++11中的元祖std::tuple就是一个可变模板类,它的定义如下: template< class... 下面看一下展开变参类模板中的参数包的方法。 2.2.1偏特化与递归方式展开 变参类模板的展开一般需要定义两到三个类,包括类声明和偏特化的类模板。 Indexes> struct MakeIndexes3<0, Indexes...> { typedef IndexSeq<Indexes...> type; }; 3.变参模板的应用 我们可以利用递归以及偏特化等方法来展开模板参数包
模板方法模式 不知道你有没有注意过,我们实现某个业务功能,在不同的对象会有不同的细节实现, 以前说过策略模式, 策略模式是将逻辑封装在一个类(提到的文章中的Duck)中,然后使用委托的方式解决。 模板方法模式的角度是:把不变的框架抽象出来,定义好要传入的细节的接口.
必定有钩子(没有实现的方法,需要子类去实现)和实现的方法。 定义 模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤的实现延迟到子类中。 模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤的具体实现。 线程池中的模板方法模式 ? AbstractExecutorService 中就有模板方法模式。 它实现了部分方法,也留下了钩子。 ? submit() 就是一个模板方法,它方法体里调用的父接口 Executor 的 execute() 方法其实并没有实现,而是交给子类去实现。 常见的模板方法模式 Spring 中 JdbcTemplate, 就是替我们封装了一套模板,我们在使用的时候只需要写 CRUD 就可以了,并不需要去释放资源和获取数据库链接。 HttpServlet 中的 doGet,doPost 方法 java.util.Arrays 的 sort 方法 优点 很好的实现了代码重用,可以将代码的不变部分和可变部分分离出来,写一个模板,实现不变部分
前言 在上一篇文章责任链模式中提到了模板方法模式,因此这里简单介绍一下. 模板方法模式比较简单,或者说比较常用.在开发过程中,许多人在不知不觉的情况下就会使用,只要他具有良好的面对对象思维. 介绍(摘自《Head FIrst 设计模式》) 在一个方法中定义一个算法的骨架,而将一些详细的步骤延迟到子类中. 模板方法使得子类可以在不改变算法结果的基础上,重新定义算法中的某些步骤. 类图 ? 角色 抽象模板: 抽象模板一般有一个具体实现的方法,用来定义算法的基础骨架.还有一些抽象方法留给子类去具体实现.此外还有一些有默认实现的钩子方法.子类可选实现. 具体模板: 继承父类的具体方法,实现他们的抽象方法,对于钩子方法,可以根据自身情况决定是都重写. 举个栗子 书上的例子好多了,网络上也有很多,我自己临时瞎想一个吧,不保证一定合适. 总结 首先注意一下:在模板方法的attack上,添加了final关键字,可以防止该方法被重写,可以保证attack这一方法,在定义及流程上的正确性及安全性,而具体的实现可以交给子类.
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/138377.html原文链接:https://javaforall.cn
类模板与友元 #include<iostream> #include<string> using namespace std; //提前让编译器知道person类存在 template<class T1 > void printPerson1(person<T1, T2>& p) { cout << "姓名:" << p.name << " 年龄:" << p.age << endl; } //类模板与友元 class T2> class person { //全局函数做友元在类内实现(一般是只写函数声明,不做定义) friend void printPerson(person<T1,T2>&p) //类模板对象做函数参数 { cout << "姓名:" << p.name << " 年龄:" << p.age << endl; } //全局函数做友元在类外实现 //1.加空模板参数列表 //2.如果是全局函数