设计模式——模板设计模式(Template Method)

模板设计-base

什么是模板?

举个简单的例子,以AABB的格式,写出一个词语,你可能会想到,明明白白,干干净净等,
这个AABB就是一个模板,对模板心中有了一个清晰的概念之后,我们再来看今天我们的内容,模板设计。

实现思路

我们在父类中,定义处理流程的框架,子类中实现具体处理

要如何实现这样的思路呢?

在父类中定义多个抽象方法,然后由一个模板方法来进行调用,决定如何使用这些模板方法,就形成了处理流程的框架。

子类继承父类,只需要实现抽象方法。这样一来模板方法就留在了父类中,各个子类都可以有自己的实现方式。

代码实现

在这里插入图片描述

在这里插入图片描述

我们定义AbstractDisplay作为父类里面有open、print、close 3个抽象方法,一个display模板方法

charDisplay和StringDisplay作为AbstractDisplay的子类,去实现各自的open、print、close方法。
最终我们用子类统一去调用父类已经实现的display模板方法,查看效果。

public abstract class AbstractDisplay {
    /**
     * 交给字类实现的抽象方法(1) open
     */
    public abstract void open();
    /**
     * 交给字类实现的抽象方法(2)print
     */
    public abstract void print();
    /**
     * 交给字类实现的抽象方法(3)close
     */
    public abstract void close();

    /**
     * 模板方法,先调用open在调用5次print方法,最后调用close。
     * 可以看出,父类中只调用抽象方法,但不实现抽象方法,具体实现交给子类。
     */
    public final void display(){
        open();
        for (int i = 0; i < 5; i++) {
            print();
        }
        close();
    }
}

接下来让我们看看CharDisplayStringDisplay是如何实现的。

public class CharDisplay extends AbstractDisplay{
    private char character;

    public CharDisplay(char c){
        this.character = c;
    }

    @Override
    public void open() {
        System.out.print("<<");
    }

    @Override
    public void print() {
        System.out.print(character);
    }

    @Override
    public void close() {
        System.out.println(">>");
    }
}
public class StringDisplay extends AbstractDisplay{

    private String string;
    private Integer times;

    public StringDisplay(String string) {
        this.string = string;
        times = string.toCharArray().length;
    }



    @Override
    public void open() {
        System.out.print("+");
        for (int i = 0; i < times; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }

    @Override
    public void print() {
        System.out.println("|"+string+"|");
    }

    @Override
    public void close() {
        System.out.print("+");
        for (int i = 0; i < times; i++) {
            System.out.print("-");
        }
        System.out.println("+");
    }
}

让我们在Main类中调用试试看吧

public class Main3 {
    public static void main(String[] args) {
        //生成一个持有'H'的CharDisplay实例
        AbstractDisplay d1 = new CharDisplay('H');
        //生成一个持有'Hello,world.'的StringDisplay类的实例
        AbstractDisplay d2 = new StringDisplay("Hello,world.");
        //由于d1、d2都是AbstractDisplay的实例,可以调用继承的display方法,实际的程序行为取决于CharDisplay类和StringDisplay类的具体实现
        d1.display();
        d2.display();
    }
}

输出结果
在这里插入图片描述
我们创建了一个AbstractDisplay的模板,最终却生成了两种不同的结果!就像AABB的模板最终可以生成明明白白和干干净净一样!

恭喜你!!掌握了模板设计模式的基本使用!接下来让我们拓展一下思路。

思路拓展

可以使逻辑处理通用化

使用 Template Method模式究竟能带来什么好处呢?

让我们先看看Template Method模式的类图是什么样的
在这里插入图片描述

使用 Template Method模式究竟能带来什么好处呢?

这里,它的优点是由于在父类的模板方法中编写了算法,因此无需在每个子类中再重复编写算法。

例如,我们没使用 Template Method模式,而是使用文本编辑器的复制和粘贴功能编写了多个ConcreteClass角色。此时,会出现ConcreteClass1、ConcreteClass2、Concreteclass3 等很多相似的类。编写完成后立即发现了Bug还好,但如果是过一段时间才发现在Concreteclass1中有 Bug,该怎么办呢?这时,我们就必须将这个 Bug的修改反映到所有的 ConcreteClass 角色中才行。

关于这一点,如果是使用 Template Method模式进行编程,当我们在模板方法中发现Bug时只需要修改模板方法即可解决问题

父类与子类之间的协助

在 Template Method模式中,父类和子类是紧密联系、共同工作的。因此,在子类中实现父类中声明的抽象方法时,必须要理解这些抽象方法被调用的时机。在看不到父类的源代码的情况下想要编写出子类是非常困难的。

模板设计-plus

练习题一

java.io.Inputstream类使用了Template Method模式。请阅读官方文档(JDK的API参考资料 ),从中找出需要用java.io.Inputstream 的子类去实现的方法。

练习题二

上面给出的AbstractDisplay类的display方法如下

public final void display(){
	....
}
这里使用了final修饰符,请问这是想表达什么意思呢?

练习题三

如果想要让示例程序中的open、print、close方法可以被具有继承关系的类和同一程序包中的类调用,但是不能被无关的其他类调用,应当怎么做呢?

练习题四

Java中的接口与抽象类很相似。接口同样也是抽象方法的集合,但是在TemplateMethod 模式中,我们却无法使用接口来扮演AbstractClass角色,请问这是为什么呢?

答案

练习题一

查阅文档后,你就会知道,InputStream是一个抽象类,其中需要子类实现的抽象方法只有一个就是read方法啦!
在这里插入图片描述

在这里插入图片描述

练习题二

final关键字修饰方法的时候,表示定义在父类中的模板方法display无法在子类中进行重写,这正和我们期望的一致,我们希望模板方法由父类直接实现,即父类直接定义抽象方法的使用框架,不希望子类再去进行重写,使用模板设计模式时,子类也不应该重写模板方法。

练习题三

可以将AbstractDisplay类中的open,print,close方法的可见性声明为protected。这样就可以让继承该类的子类调用这些方法,而其他包中的类无法调用这些方法(不过同一个包中的类依然可以调用这些方法)。

练习题四

这是因为 TemplateMethod模式中的AbstractClass角色必须实现处理的流程。在抽象类中可以实现一部分方法(例如 AbstractDisplay类中的display方法),但是在接口中是无法实现方法的。因此,在TemplateMethod 模式中,无法用接口替代抽象类。

在Java8之前以上结论成立,在Java8之后,引入了defualt关键字,增强了接口的功能,使得接口也可以实现方法。

知识关联性

Factory Method 模式(工厂模式)

是将 Template Method 模式用于生成实例的一个典型例子。

Strategy模式(策略模式)

在 Template Method 模式中,可以使用继承改变程序的行为。这是因为 Template Method 模式在父类中定义程序行为的框架,在子类中决定具体的处理。
与此相对的是 Strategy模式,它可以使用委托改变程序的行为。与Template Method 模式中改变部分程序行为不同的是,Strategy模式用于替换整个算法。

模板设计模式(Template Method)的讲解到此就结束啦,感谢阅读。💕

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

draw.text((left, top - 15), text,font=font, fill=“green”)

这是一个Python PIL库中的方法&#xff0c;用于在图片上绘制文本。具体来说&#xff0c;它可以在指定的位置绘制指定的文本&#xff0c;并使用指定的字体、颜色等参数进行渲染。其中&#xff0c;left和top是文本绘制的左上角坐标&#xff0c;text是要绘制的文本内容&#xff0c…

揭秘高效引流获客的艺术:转化技巧大公开

在数字化营销的海洋中&#xff0c;每个企业都如同一艘努力航行的船&#xff0c;而流量便是推动船只前行的风帆。如何有效吸引并获取潜在客户&#xff0c;即所谓的“引流获客”&#xff0c;已成为企业市场营销策略中不可或缺的一环。本文将详细探讨几种实用且高效的引流获客技巧…

Vue从入门到实战Day04

一、组件的三大组成部分&#xff08;结构/样式/逻辑&#xff09; 1. scoped样式冲突 默认情况&#xff1a;写在组件中的样式会全局生效 -> 因此很容易造成多个组件之间的样式冲突问题。 1. 全局样式&#xff1a;默认组件中的样式会作用到全局 2. 局部样式&#xff1a;可以…

0X JavaSE-- UML、

# Unified Modeling Language UML 统一建模语言 UML 是一种图形化的语言。 UML 不是专门为 Java 准备的。 只要是面向对象的编程语言&#xff0c;开发前的设计&#xff0c;都需要画 UML 图进行系统设计。 最常用的四个 UML 图是 类图&#xff08;Class Diagram&#xff09;&…

微信小程序踩坑,skyline模式下,简易双向绑定无效

工具版本 基础库版本 Skline模式 页面json设置 问题描述 skyline模式下,textarea,input标签设置简易双向绑定 model:value是无效的,关闭skyline模式就正常使用了 截图展示 这里只展示了textarea标签,input标签的简易双向绑定也是无效的 总结 我在文档里面是没找到skyline里面不…

考研踩坑经验分享

文章目录 写在前面自身情况简介自身学习路线优点坑点 学习路线建议1、2和3月份3、4和5月份6、7和8月份9、10月份11、12月份 一些私货建议结尾 写在前面 考研是一件非常有盼头的事&#xff0c;但绝对不是一件容易的事。 如果你不能做好来年三月份出成绩时&#xff0c;坦然接受…

英语复习之英语形近词总结(四)

英语形近词总结复习第四部分&#xff1a; 单词 释义例句 genuine 英 /ˈdʒenjuɪn/ 美 /ˈdʒenjuɪn/ adj.真实的&#xff0c;真正的&#xff1b;诚恳的 1.Only genuine refugees can apply for asylum. 只有真正的难民才能申请政治避难。 《牛津词典》 2.This isnt a genui…

Leaflet.canvaslabel在Ajax异步请求时bindPopup无效的解决办法

目录 前言 一、场景重现 1、遇到问题的代码 2、问题排查 二、通过实验验证猜想 1、排查LayerGroup和FeatureGroup 2、排查Leaflet.canvaslabel.js 三、柳暗花明又一村 1、点聚类的办法 2、歪打正着 总结 前言 在上一篇博客中介绍了基于SpringBoot的全国风景区WebGIS按…

扑克游戏程序代码,使用QT,C++ (price 600 不包含文档)

wx:help-assignment code price: 600 &#xff08;不包含文档&#xff01;不包含文档&#xff01;不包含文档&#xff01;&#xff09; 扑克游戏程序代码&#xff0c;使用QT&#xff0c;C 1.作业的目的是 在这个作业中&#xff0c;你将得到一组要求&#xff0c;使用本模块中涵…

java项目之英语知识应用网站源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的英语知识应用网站。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 英语知识应用网站的主要…

kafka安装及收发消息

kafka需要与zookeeper配合使用&#xff0c;但是从2.8版本kafka引入kraft&#xff0c;也就是说在2.8后&#xff0c;zookeeper和kraft都可以管理kafka集群&#xff0c;这里我们依然采用zookeeper来配合kafka。 1、首先我们下载zookeeper 下载地址为 https://zookeeper.apache.org…

macOS12安装 php8.1和apache

1. 安装php 8.1 macOS12不再自带php brew tap shivammathur/php 查看可安装版本 brew search php 安装指定版本 brew install php8.1 环境配置 vim ~/.zshrc export PATH"/usr/local/opt/php8.1/bin:$PATH" export PATH"/usr/local/opt/php8.1/sbin:$PAT…

《工具分享-整合功能网页》标星5.3k⭐开发人员的在线工具集:it-tools

IT Tools - 为方便开发人员提供的在线工具 部署自己的it-tools: 有两个版本&#xff0c;目前有中文支持。 直接部署使用docker指令获取出来的是英文的&#xff1a; 英文版&#xff1a; docker run -d --name it-tools --restart unless-stopped -p 8080:80 corentinth/it-…

第81天: 代码审计-PHP 项目MVC 注入CNVD 拿 1daySQL监控动态调试

目录 前置知识 正则表达式挖掘思路(通用漏洞思路) 功能点挖掘思路(通用漏洞思路) 案例一&#xff1a;数据库监控-QQ 业务源码系统-(无过滤) 案例二&#xff1a;正则表达式-Bluecms 源码系统-(无过滤) 案例三&#xff1a; CNVD 拿 1DAY-梦想 CMS 源码系统-(有过滤) 梦想 …

二、使用插件一键安装HybridCLR

预告 本专栏将介绍如何使用这个支持热更的AR开发插件&#xff0c;快速地开发AR应用。 专栏&#xff1a; Unity开发AR系列 插件简介 通过热更技术实现动态地加载AR场景&#xff0c;简化了AR开发流程&#xff0c;让用户可更多地关注Unity场景内容的制作。 热更方案 基于Hybri…

STM32系统架构

以下是STM32系统架构中的各个重要组件和功能&#xff1a; 组件描述Cortex-M内核ARM Cortex-M系列内核&#xff0c;如M0、M0、M3、M4、M7等Flash存储器存储程序代码和数据SRAM存储程序运行时数据和堆栈外设接口GPIO、SPI、I2C、UART、TIM、ADC、DAC、USB、CAN、Ethernet等时钟和…

Android动画(四):PathMeasure实现路径动画

文章概览 1 PathMeasure概述2 实现路径加载动画3 实现箭头加载动画4 实现操作成功动画 本系列将介绍以下内容&#xff1a; Android动画 1 PathMeasure概述 PathMeasure是一个单独的类&#xff0c;其全部源码如下&#xff08;请详细研读注释&#xff09;&#xff1a; package…

吃透前端文件上传与文件相关操作

最近在学文件上传的操作,所以想把学习到东西写成一文章 这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的 前端文件上传 我首先想到是 <input type"file">选择文件</input>如果我们想限制上传文件的格式,大小或进行裁剪分片上传…

ssm121开放式教学评价管理系统+vue

开放式教学评价管理系统vue 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对开放式教学评价管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了开放式开放…

C++类与对象的一些练习

1.设计一个名为Rectangle的矩形类&#xff0c;其属性为矩形的长和宽&#xff0c;能计算和输出矩形的周长和面积。 class Rectangle { public:Rectangle(int c0,int k0):m_c(c),m_k(k){}int length()//周长{return 2 * (m_c m_k);}int area()//面积{return m_c * m_k;} privat…