设计模式(二)模板方法模式

1.模版方法模式简介

模版方法模式介绍

在软件开发中,有时会遇到类似的情况,某个方法的实现需要多个步骤,其中有些步骤是固定的,而有些步骤并不固定,存在可变性。为了提高代码的复用性和系统的灵活性,可以使用模板方法模式来应对这类情况。

模版方法模式定义

定义一个操作中的算法框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。

模版方法模式结构图

  • AbstractClass:抽象类,定义了一套算法。
  • ConcreteClass:具体实现类。

2.模版方法模式的简单实现

①创建抽象类,定义算法框架

一个武侠要战斗的时候,也有一套固定的通用模式,那就是运行内功、开通经脉、准备武器和使用招式,我们把这些用代码表示就是:

 1 public abstract class AbstractSwordsman {
 2     //该方法为final,防止算法框架被覆写
 3     public final void fighting(){
 4        //运行内功,抽象方法
 5        neigong();
 6        //调整经脉,具体方法
 7        meridian();
 8        //如果有武器则准备武器
 9        if(hasWeapons()) {
10            weapons();
11        }
12        //使用招式
13        moves();
14        //钩子方法
15        hook();
16    }
17     //空实现方法
18     protected void hook(){}
19     protected abstract void neigong();
20     protected abstract void weapons();
21     protected abstract void moves();
22     protected void meridian(){
23         System.out.println("开通正经与奇经");
24     }
25 
26     /**
27      * 是否有武器,默认是有武器的,钩子方法
28      * @return
29      */
30     protected boolean hasWeapons(){
31          return true;
32     }
33 }

需要注意的是这个抽象类包含了三种类型的方法,分别是抽象方法、具体方法和钩子方法。抽象方法是交由子类去实现,具体方法则在父类实现了子类公共的方法实现,在上面的例子就是武侠开通经脉的方式都一样,所以就在具体方法中实现。钩子方法则分为两类,第一类是15行,它有一个空实现的方法,子类可以视情况来决定是否要覆盖它;第二类则是第9行,这类钩子方法的返回类型通常是bool类型的,一般用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行。

②定义具体实现类

本文就拿张无忌、张三丰来作为例子:

 1 public class ZhangWuJi extends AbstractSwordsman {
 2 
 3     @Override
 4     protected void neigong() {
 5         System.out.println("运行九阳神功");
 6     }
 7 
 8     @Override
 9     protected void weapons() {
10     }
11 
12     @Override
13     protected void moves() {
14         System.out.println("使用招式乾坤大挪移");
15     }
16 
17     @Override
18     protected boolean hasWeapons() {
19         return false;
20     }
21 }

张无忌没有武器所以hasWeapons方法返回false,这样也不会走weapons方法了。

 1 public class ZhangSanFeng extends AbstractSwordsman {
 2 
 3     @Override
 4     protected void neigong() {
 5         System.out.println("运行纯阳无极功");
 6     }
 7 
 8     @Override
 9     protected void weapons() {
10         System.out.println("使用真武剑");
11     }
12 
13     @Override
14     protected void moves() {
15         System.out.println("使用招式神门十三剑");
16     }
17 
18     @Override
19     protected void hook() {
20         System.out.println("突然肚子不舒服,老夫先去趟厕所");
21     }
22 }

最后张三丰突然肚子不舒服所以就实现了钩子方法hook。

③客户端调用

1 public class Client {
2     public static void main(String[] args) {
3         ZhangWuJi zhangWuJi=new ZhangWuJi();
4         zhangWuJi.fighting();
5         ZhangSanFeng zhangSanFeng=new ZhangSanFeng();
6         zhangSanFeng.fighting();
7     }
8 }

运行结果:
运行九阳神功
开通正经与奇经
使用招式乾坤大挪移
运行纯阳无极功
开通正经与奇经
使用真武剑
使用招式神门十三剑
突然肚子不舒服,老夫先去趟厕所

 

3.模版方法模式的优缺点和使用场景

优点

  • 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
  • 子类实现算法的某些细节,有助于算法的扩展。

缺点

  • 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。

使用场景

  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
  • 面对重要复杂的算法,可以把核心算法设计为模版方法,周边相关细节功能则有各个子类实现。
  • 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

命令行程序

1 package com.jdk7.chapter1;2 3 /**4 * 命令行程序5 * author celineluo6 *7 */8 public class CommandArgs {9 /** 10 * 调用系统错误方法打印错误信息 11 * 调用exit()关闭java虚拟机,0表示正常退出应用程序,其他值表示异常退出应…

题解 P2598 【[ZJOI2009]狼和羊的故事】

P2598 [ZJOI2009]狼和羊的故事 题目描述 “狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想&am…

Spring Data Solr教程:排序

当我们实现单词搜索功能时,我们通常希望通过使用每个搜索结果的相关性以降序对搜索结果进行排序。 这也是Solr的默认行为。 但是,在某些情况下,有必要手动指定排序顺序。 一种此类情况是“常规”搜索功能的实现,该功能已在我的Sp…

浅谈Java中的hashcode方法

浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率。在Java的Object类中有一个方法: 1public native int hashCode();根据这个方法的声明可知,该方法返回一个int类型的数值,并…

前端机试面试题

一、题目要求 1、请实现“https://channel.jd.com/fashion.html”超值购部分内容。 2、使用CSS DIV实现页面布局,页面居中,文字颜色效果要求一致。40分 3、鼠标悬停时的动画效果。10分 4、“进入查看”标签与样式。10分 5、定义一个javascript数组&…

三分大法好

三分算法解决凸形或者凹形函数的极值; 如下图 lmid (Left Right) / 2 rmid (lmid Right) / 2; 如果lmid靠近极值点,则Right rmid; 否则(即midmid靠近极值点),则Left lmid; 例题的话在我的博客相关分类中找. 转载于:https://w…

java stopself_如何正确停止前台服务?

我不知道它是否正确,但在我的应用程序中,我正在停止前台服务,它可以工作。请检查代码private void stopForegroundService() {// Stop foreground service and remove the notification.stopForeground(true);// Stop the foreground service.stopSelf();}更新打电话给stopserv…

将内存消耗减少20倍

这将是另一个故事,与我们分享有关内存相关问题的最新经验。 该案例是从最近的客户支持案例中提取的,在该案例中,我们遇到了一个行为异常严重的应用程序,该应用程序因生产中的OutOfMemoryError消息而死亡。 在连接了Plumbr的情况下…

Flex 布局教程:实例篇

该教程整理自 阮一峰Flexible教程 今天介绍常见布局的Flex写法。你会看到,不管是什么布局,Flex往往都可以几行命令搞定。 我的主要参考资料是Landon Schropp的文章和Solved by Flexbox。 一、骰子的布局 骰子的一面,最多可以放置9个点。 下面…

在Windows运行Python程序

在Windows运行Python程序 转载于:https://www.cnblogs.com/macT/p/9289091.html

基于java的网上花店销售系统_基于web的花店销售系统的设计与实现

基于web的花店销售系统的设计与实现(论文13000字)摘要:本系统是一个相对简单的基本应用系统,主要满足传统的花店运营需要,将自己的销售渠道扩展到网上,通过简单的管理,提供给最终消费者产品的展现、购物、订单处理等实…

mysql安装及一些配置

apt-get updateapt-get install mysql-server$mysql -u root#修改密码root密码为123456mysql> GRANT ALL PRIVILEGES ON *.* TO rootlocalhost IDENTIFIED BY "123456";#创建数据库xxxmysql>CREATE DATABASE xxx;#创建一个账户 xxx_root对数据库xxx有全部权限&…

Apache Server和JMeter调试

我一直在使用JMeter为生产服务器生成负载以测试我的应用程序。 该测试计划具有13个以上的HTTP采样器以发出不同的请求,并具有一个正则表达式提取器以从响应中提取一些值。 此值在连续的HTTP Sampler中使用。 这个测试用例简单而直接。 最初,我使用200个J…

Flexible 弹性盒子模型之flex

实例 让所有弹性盒模型对象的子元素都有相同的长度,忽略它们内部的内容: #main div{flex:1;} 复制 效果预览 浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号。 紧跟在 -webkit-, -ms- 或 -moz- 后的数字为支持该前缀属性的第一个版本。 …

java冒泡遍历对象_Java经典排序算法(冒泡、选择、插入)

排序算法说明排序说明对一序列对象根据某个关键字进行排序。术语说明稳定:如果a原本在b前面,而ab,排序之后a仍然在b的前面;不稳定:如果a原本在b的前面,而ab,排序之后a可能会出现在b的后面&#…

create your own github repository and build link to your local project

1. create a repository in you github.  i.e. repository name: spring5_exercise 2. initial git profile in your local project root directory. echo "# spring5_exercise" >> README.md git init git add README.md git commit -m "first commit&…

快速分类–三向和双枢轴

毫无疑问,Quicksort被认为是本世纪最重要的算法之一,并且它是许多语言(包括Java中的Arrays.sort )的事实上的系统排序。 那么,quicksort有何新功能? 嗯,除了我现在(在Java 7发行了2…

mysql workbench启动_怎么启动mysql workbench

答:你好,方法/步骤 如下: 双击或右键打开MySQL Workbench,进入软件主界面。 点击new connection,会有个弹出框,让我们填写user(用户名),password(密码)。 填写完用户名和密码,点击确定就会出现我…

在jekyll模板博客中添加网易云模块

最近使用GitHub Pages Jekyll 搭建了个人博客,作为一名重度音乐患者,博客里面可以不配图,但是不能不配音乐啊。 遂在博客里面引入了网易云模块,这里要感谢网易云的分享机制,对开发者非常友好: 1.每首歌曲…

C# Timer定时器用法

System.Timers.Timer timer1 new System.Timers.Timer(); timer1.Elapsed new System.Timers.ElapsedEventHandler((obj, eventArg) > {Console.WriteLine("aaa"); }); timer1.Interval 2000;//毫秒 1秒1000毫秒 timer1.Enabled true;//必须加上 timer1.AutoR…