打败全国百分之99.99的模板方法模式讲解

news2024/11/18 17:30:43

目录

  • 背景:
  • 模板方法定义:
  • 步骤:
    • 初始版: 每个人都抄卷子,然后抄完写自己的答案
    • 第一版:将试卷的题抽象出来
    • 第二版:将每个人回答的部分抽象出来
    • 第三版:将答题步骤封装出来(这里书上写的比较灵活)
    • 版本4:基于大话设计模式上版本三展开想象回归业务,这里的所谓步骤仅仅是答题顺序吗,是不是还有别的可能(如A要先吃饭再睡觉,B要先做第一题再做第二题)
    • 版本5:基于书上的代码是不是可以推断出来只要是至少包含两个方法的代码,都可以使用模板方法(方法个数)
  • 分析
    • 自动化代码:
    • 未来展望:
  • 总结:

背景:

为什么要学习设计模式?
面向对象设计思想分为几层:

Spring相关代码
设计模式
软件七大设计原则
复用扩充维护
封装继承多态
抽象

这样就可以看出来,设计模式处在承上启下的重要位置,只有把设计模式学好,我们才能更加深刻理解Spring。

模板方法定义:

定义一个操作中的算法骨架,而将一些步骤延迟到子类中,模板方法是的子类可以不改变一个算法的结构即可重定义改算法的某些特定步骤。
在这里插入图片描述

步骤:

业务场景:两个人做一套卷子,两个人有自己的答案。

初始版: 每个人都抄卷子,然后抄完写自己的答案

package com.example.Template.v1;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 10:26
 * @Version: 1.0
 */

public class Client {
    public static void main(String[] args) {
        TestPaperA   studentA = new TestPaperA();
        studentA.testQueation1();
        studentA.testQueation2();
        studentA.testQueation3();

        TestPaperB   studentB = new TestPaperB();
        studentB.testQueation1();
        studentB.testQueation2();
        studentB.testQueation3();

    }

}

package com.example.Template.v1;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 09:27
 * @Version: 1.0
 */

public class TestPaperA {
    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子");
        System.out.println("答案:B");
    }


    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语");
        System.out.println("答案:B");
    }


    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色");
        System.out.println("答案:B");
    }


}

package com.example.Template.v1;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 09:27
 * @Version: 1.0
 */

public class TestPaperB {
    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子");
        System.out.println("答案:A");
    }


    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语");
        System.out.println("答案:A");
    }


    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色");
        System.out.println("答案:A");
    }


}

package com.example.Template.v1;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 09:27
 * @Version: 1.0
 */

public class TestPaperB {
    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子");
        System.out.println("答案:A");
    }


    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语");
        System.out.println("答案:A");
    }


    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色");
        System.out.println("答案:A");
    }


}

第一版:将试卷的题抽象出来

public class Client {
    public static void main(String[] args) {
        TestPaperA studentA = new TestPaperA();
        studentA.testQueation1();
        studentA.testQueation2();
        studentA.testQueation3();

        TestPaperB studentB = new TestPaperB();
        studentB.testQueation1();
        studentB.testQueation2();
        studentB.testQueation3();

    }

}
package com.example.Template.v2;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v2
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 10:32
 * @Version: 1.0
 */

public class TestPaper {

    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子");

    }


    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语");

    }


    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色");

    }
}

package com.example.Template.v2;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 09:27
 * @Version: 1.0
 */

public class TestPaperA extends   TestPaper{
    public  void testQueation1(){
      super.testQueation1();
        System.out.println("答案:B");
    }


    public  void testQueation2(){
        super.testQueation2();
        System.out.println("答案:B");


    }


    public  void testQueation3(){
        super.testQueation3();
        System.out.println("答案:B");
    }


}

package com.example.Template.v2;

/**
 * @BelongsProject: JAVAtest
 * @BelongsPackage: com.example.Template.v1
 * @Author: GuoYuan.Zhao
 * @Description: 描述什么人干什么事儿
 * @CreateTime: 2023-09-14 09:27
 * @Version: 1.0
 */

public class TestPaperB {
    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子");
        System.out.println("答案:A");
    }


    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语");
        System.out.println("答案:A");
    }


    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色");
        System.out.println("答案:A");
    }


}

第二版:将每个人回答的部分抽象出来

public class Client {
    public static void main(String[] args) {
        TestPaperA studentA = new TestPaperA();
        studentA.testQueation1();
        studentA.testQueation2();
        studentA.testQueation3();

        TestPaperB studentB = new TestPaperB();
        studentB.testQueation1();
        studentB.testQueation2();
        studentB.testQueation3();

    }
public class TestPaper {

    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子"+"答案"+ getAnswer1());

    }

    public String getAnswer1(){
        return "A";
    }



    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语"+getAnswer2());

    }


    public String getAnswer2(){
        return "A";
    }

    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色"+getAnswer3());

    }

    public String getAnswer3(){
        return "A";
    }
}

public class TestPaperA extends TestPaper {
    public String getAnswer1(){
        System.out.println("A");
        return "A";
    }

    public String getAnswer2(){
        System.out.println("A");

        return "A";
    }

    public String getAnswer3(){
        System.out.println("A");

        return "A";
    }


}
public class TestPaperB  extends  TestPaper {
    public String getAnswer1(){
        System.out.println("B");

        return "B";
    }

    public String getAnswer2(){
        System.out.println("B");

        return "B";
    }

    public String getAnswer3(){
        System.out.println("B");

        return "B";
    }


}

第三版:将答题步骤封装出来(这里书上写的比较灵活)

public class Client {
    public static void main(String[] args) {
        TestPaperA studentA = new TestPaperA();
        studentA.templateMethod();

        TestPaperB studentB = new TestPaperB();
        studentB.templateMethod();

    }

}
public class TestPaper {

    public  void testQueation1(){
        System.out.println("你喜欢吃啥东西呢?   A:苹果  B:香蕉    c:橙子"+"答案"+ getAnswer1());

    }

    public String getAnswer1(){
        return "A";
    }



    public  void testQueation2(){
        System.out.println("你喜欢的学科是啥呢?   A:语文  B:数学    c:英语"+getAnswer2());

    }


    public String getAnswer2(){
        return "A";
    }

    public  void testQueation3(){
        System.out.println("你喜欢的颜色是啥呢?   A:红色  B:绿色    c:蓝色"+getAnswer3());

    }

    public String getAnswer3(){
        return "A";
    }


    public  void   templateMethod(){
        this.testQueation1();
        this.testQueation2();
        this.testQueation3();
    }
}
public class TestPaperA extends TestPaper {
    public String getAnswer1(){
        System.out.println("A");
        return "A";
    }

    public String getAnswer2(){
        System.out.println("A");

        return "A";
    }

    public String getAnswer3(){
        System.out.println("A");

        return "A";
    }


}

public class TestPaperB  extends TestPaper {
    public String getAnswer1(){
        System.out.println("B");

        return "B";
    }

    public String getAnswer2(){
        System.out.println("B");

        return "B";
    }

    public String getAnswer3(){
        System.out.println("B");

        return "B";
    }


}

版本4:基于大话设计模式上版本三展开想象回归业务,这里的所谓步骤仅仅是答题顺序吗,是不是还有别的可能(如A要先吃饭再睡觉,B要先做第一题再做第二题)

版本5:基于书上的代码是不是可以推断出来只要是至少包含两个方法的代码,都可以使用模板方法(方法个数)

分析

package com;
 
abstract class AbstractClass {
	public abstract void PrimitiveOperation1();
	public abstract void PrimitiveOperation2();
	
	public void templateMethod(){
		PrimitiveOperation1();
		PrimitiveOperation2();
	    System.out.println(    );
	}
}
****************
package com;
 
public class ConcreteClassA extends AbstractClass{
 
	
	public void PrimitiveOperation1() {
		// TODO Auto-generated method stub
		System.out.println("A的具体方法1");
	}
 
	
	public void PrimitiveOperation2() {
		// TODO Auto-generated method stub
		System.out.println("A的具体方法2");
	}
 
}
*******************
package com;
 
public class ConcreteClassB extends AbstractClass{
	
	public void PrimitiveOperation1() {
		// TODO Auto-generated method stub
		System.out.println("B的具体方法1");
	}
 
	
	public void PrimitiveOperation2() {
		// TODO Auto-generated method stub
		System.out.println("B的具体方法2");
	}
 
}
****************
 
package com;
 
public class Main {
 
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AbstractClass c;
		c=new ConcreteClassA();
		c.templateMethod();
		c=new ConcreteClassB();
		c.templateMethod();
		
	}
 
}

看上边的代码是不是可以激发你的想象力吗?
模板方法中的templateMethod 方法中打印最后一行空格给大家留下了想象的空间,是第三个题目还是为了让输入结果错开,看着分界线明显呢。

概念里边说的骨架,
1、并不仅仅是templateMethod 中定义了执行方法的顺序
2、还有这几个方法本身就是骨架,子类大概率会重写抽象类中的抽象方法(方法名一样,返回类型一样,这不算是骨架吗)

体现了依赖倒置:
templateMethod 中调用了PrimitiveOperation2和PrimitiveOperation1,但是
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();

这俩方法在父类中根本没有具体实现,只有真正到子类的时候,去执行子类中的具体方法,
倒置是什么意思?
细节依赖于抽象:子类方法起名要按照父类起,且在客户端子类对象.templateMethod (),运行起来要按照父类templateMethod 方法的代码步骤执行。
是抽象不依赖于细节:抽象类中的方法名和templateMethod 中的方法先后顺序不会因为子类发生变化而改变。

自动化代码:

子类可以抽出模板:

public class ConcreteClassX extends AbstractClass{
	
	public void PrimitiveOperation1() {
		//通过前端传过来
	}
 
	
	public void PrimitiveOperation2() {
		//通过前端传过来
	}
 
}

可以看到客户端也有重复性代码:
AbstractClass c;
c=new ConcreteClassA();
c.templateMethod();
c=new ConcreteClassB();
c.templateMethod();
也可以通过模板实现

未来展望:

客户端部分可以拆成和策略模式一样,任意组合创建不同的子类对象。
再进一步灵活加上工厂方法,就可以自动配置组合方式。(客户端传参)

总结:

从版本1开始,我们一步步增加灵活性,多维度思考,主要围绕复用扩充维护三方面考虑,代码越来越灵活。

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

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

相关文章

lenovo联想Legion Y9000P IRX8H 2023款(82WQ)原装出厂Windows11系统

联想拯救者笔记本电脑原厂系统自带网卡、显卡、声卡等所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 链接:https://pan.baidu.com/s/1YBji_oh7xOkq-NxnS8Mm8g?pwdn17o 提取码:n17o 所需要工具:16G或以上的U盘 文件…

el-table 列背景色渐变

最初的想法是&#xff0c;给每一行添加背景色&#xff0c;逐行递减透明度&#xff0c;发现结果比较突兀&#xff0c;效果如下&#xff1a; 如果有需要这种样式的&#xff0c;代码如下&#xff1a; <template><div><el-table:data"tableData":heade…

小麦苗GreenPlum学习大纲

腾讯文档 课程文档内容如下&#xff1a; 小麦苗GreenPlum课程公开课-- 数据库通用学习路线、答疑、培训、考证等&#xff1a;https://docs.qq.com/doc/p/b65bcd7647a9974a94b97fb06d04a089c25a7f0c 小麦苗GreenPlum课程第0节-- 数据库简介、分类、发展、流行度排名等&#xf…

Docker容器化技术(从零学会Docker)

文章目录 前言一、初识Docker1.初识Docker-Docker概述2.初识Docker-安装Docker3.初识Docker-Docker架构4.初识Docker-配置镜像加速器 二、Docker命令1.Docker命令-服务相关命令2.Docker命令-镜像相关命令3.Docker命令-容器相关命令 三、Docker容器的数据卷1.Docker容器数据卷-数…

Python:函数定义的参数

相关阅读 Python专栏https://blog.csdn.net/weixin_45791458/category_12403403.html?spm1001.2014.3001.5482 函数定义就是定义一个用户自定义的函数对象&#xff0c;它的语法的BNF范式如下所示&#xff0c;有关BNF范式的规则&#xff0c;可以参考之前的文章。 funcdef …

asp.net+sqlserver+c#教师工作量计算系统

本课题主要是解决工作量管理管理中的日常中涉及到的问题&#xff0c;目标是使工作量在管理上做到数据的信息化、快速化。 系统在实现上应至少具有如下功能&#xff1a; (1)教师信息管理 该模块包括教师信息的添加、修改。 (2)个人信息 该模块是对用户登录系统后对自己信息的修改…

C-结构体

目录 结构体 定义结构体 第一种方式 定义的同时定义变量名 第三种方式 赋值和初始化 如何取出结构体成员 结构体变量&#xff0c;结构体指针作为函数参数进行传递 结构体运算 结构体 形成了一个新的数据类型 定义结构体 第一种方式 定义一个新的数据类型&#xf…

Unity - Shader Compiled Log

文章目录 吐槽开启 Log Shader Compilation实践资源准备Build ABTesting ScriptShader Compiled Log Project 吐槽 先说一下&#xff0c;最近几天前&#xff0c;纷纷看到 unity install fee 的天才收费方案 真的忍不住吐槽&#xff0c;我只想说&#xff1a; “no zuo no die”…

旋转框/微调按钮的基类--QAbstractSpinBox 类

1、 QAbstractSpinBox 类是 QWidget 类的直接子类&#xff0c;虽然该类不是抽象类&#xff0c;但该类并未提供实 际的功能&#xff0c;仅为旋转框提供了一些外观的形式以及需要子类实现了成员&#xff0c; 也就是说点击微调按钮的上/下按钮&#xff0c;不会使其中的数值有变化。…

Visual Studio批量删除换行

1. 使用ctrlh可以打开替换窗体 2.alte选择窗体中的正则表达式 使用正则表达式&#xff1a; ^\s*$ ^代表行首 $代表行尾 \s代表任意不可见字符&#xff0c;例如空格、Tab等 *代表匹配\s任意次 结果&#xff1a;

002 Linux 权限

前言 本文将会向您介绍关于linux权限方面的内容&#xff0c;包括文件类型&#xff0c;如何切换用户、基本权限、粘滞位等等 Linux具体的用户 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的…

安卓预制权限添加规则

android:protectionLevel 可以在 android/frameworks/base/core/res/AndroidManifest.xml查询 signature|preinstalled 加在 这个文件里 privapp-permissions-xx.xml dangerous 加在 default-permissions/default-mega-permissions.xml normal 不需要加 不存在两个文件都加…

【LeetCode-中等题】18. 四数之和

文章目录 题目方法一&#xff1a;双指针&#xff08;定2动2&#xff09; 题目 方法一&#xff1a;双指针&#xff08;定2动2&#xff09; 这题可以参考【LeetCode-中等题】15. 三数之和 区别在于&#xff0c;三数之和只需要用一个for循环定住一个数&#xff0c;然后设置两个前…

类和对象(3)

文章目录 1.回顾上节2. 拷贝构造3. 运算符重载&#xff08;非常重要&#xff09;4. 赋值运算符重载 1.回顾上节 默认成员函数&#xff1a;我们不写&#xff0c;编译器自动生成。我们不写&#xff0c;编译器不会自动生成 默认生成构造和析构&#xff1a; 对于内置类型不做处理对…

mysql远程连接失败

先上结论&#xff0c;只提出最容易忽略的地方 服务器是阿里云、腾讯云等平台&#xff0c;平台本身自带的防火墙没有开启iptables规则中禁用了3306&#xff0c;即使你根本没有启用iptables服务 第二条是最离谱的 从这里可以看到&#xff0c;我服务器并未启用 iptables 服务 但…

应用在电子体温计中的国产温度传感芯片

电子体温计由温度传感芯片&#xff0c;液晶显示器&#xff0c;纽扣电池&#xff0c;专用集成电路及其他电子元器件组成。能快速准确地测量人体体温&#xff0c;与传统的水银玻璃体温计相比&#xff0c;具有读数方便&#xff0c;测量时间短&#xff0c;测量精度高&#xff0c;能…

如何分析Apple搜索广告效果

Apple搜索广告提供了一系列指标&#xff0c;报告和功能&#xff0c;可为广告效果、用户行为和关键词有效性提供有价值的见解。通过利用此工具&#xff0c;广告商可以更深入地了解他们的广告活动&#xff0c;优化他们的策略&#xff0c;并取得更好的结果。 1、在研究数据之前&a…

深入解析NLP情感分析技术:从篇章到属性

目录 1. 情感分析概述1.1 什么是情感分析&#xff1f;- 情感分析的定义- 情感分析的应用领域 1.2 为什么情感分析如此重要&#xff1f;- 企业和研究的应用- 社交媒体和公共意见的影响 2. 篇章级情感分析2.1 技术概览- 文本分类的基本概念- 机器学习与深度学习方法- 词嵌入的力量…

webStorm内存溢出问题

手动启动vue项目正常运行&#xff0c;修改部分内容保存后会自动重新run一下&#xff0c; 这个时候就报错内存溢出&#xff0c;然后很悲伤的需要再手动重启一下。 每个人的情况不同&#xff0c;下面几种方法可以都试一试。 1、修改help里的内存配置 &#xff08;图片只参考修改…

puttygen工具ppk文件版本配置

有时一些程序要用到ppk密钥文件&#xff0c;如果用puttygen去生成的话&#xff0c;ppk文件版本是可以配置的&#xff0c;有版本2、版本3&#xff0c;如果出现密钥文件无效&#xff0c;可以试一下选择不用的文件版本。 配置位置&#xff1a;打开puttygen-选择菜单栏Key-选择Para…