首页 > 其他分享 >提高代码复用性与可维护性:深入剖析模板方法模式

提高代码复用性与可维护性:深入剖析模板方法模式

时间:2023-12-23 22:34:58浏览次数:42  
标签:实现 子类 复用 可维护性 包子 方法 public 模板

提高代码复用性与可维护性:深入剖析模板方法模式_后端

什么是模板方法模式

模板方法模式是一种行为型设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

在模板方法模式中,抽象类负责给出算法的轮廓和骨架(由一个或多个模板方法组成),而实现类则负责实现抽象类中所定义的抽象方法和钩子方法。模板方法模式相当于定义了一个操作中的算法的骨架,具体的特定步骤的实现延迟到子类中去定义,使得子类可以不更改一个算法的结构,就可以重新定义算法的某些特定步骤。

模板方法模式的核心原理

模板方法模式的核心原理是定义一个算法的骨架,将算法中不同的步骤延迟到子类中实现。它通过定义一个抽象类或接口作为模板,其中包含了一个或多个抽象方法和具体方法。具体方法中通常包含了算法的主要逻辑,而抽象方法则由子类去实现。

模板方法模式有以下几个核心角色:

  1. 抽象类/模板(AbstractClass/Template):这个角色是模板方法模式的核心,它定义了算法的骨架。这个类中有一个或多个模板方法,这些方法定义了算法的各个步骤。模板方法模式中的其他角色会继承这个抽象类,并实现抽象类中定义的方法。
  2. 具体子类/具体实现(ConcreteClass):这个角色是抽象类的子类,它实现了抽象类中定义的抽象方法。具体实现类需要给出抽象方法的具体实现,这些实现可能会在抽象类中的模板方法中被调用。

提高代码复用性与可维护性:深入剖析模板方法模式_后端_02

模板方法模式如何实现

需求描述与分析

编写一个制作包子的程序,说明如下:

  • 制作包子的流程:和面—>选择馅料食材—>剁馅—>制作包子;
  • 不同的馅料,可以制作出不同口味的包子;
  • 从和面直到包子出锅,这几个步骤对于制作不同馅料的包子都是一样的;

实现方法

提高代码复用性与可维护性:深入剖析模板方法模式_java_03

1、定义一个抽象模板类AbstractMakeBaozi.java:定义制作包子每一步骤的方法,定义制作包子的核心骨架方法并实现;

/**
 * 制作包子的抽象模板类
 */
public abstract class AbstractMakeBaozi {
    /**
     * 和面
     */
    public  void huoMian(){
        System.out.println("step1:和面");
    }

    /**
     * 选择馅料食材
     */
    public abstract void selectXianLiao();

    /**
     * 剁馅
     */
    public abstract void makeXianLiao();

    /**
     * 制作包子
     */
    public  void make(){
        this.huoMian();
        this.selectXianLiao();
        this.makeXianLiao();
        System.out.println("step4:制作包子");
        System.out.println("制作完成!");
    }
}

2、定义具体的制作肉馅包子的模板实现类MakeMeatBaozi.java:继承抽象模板类AbstractMakeBaozi.java,实现抽象模板类中的抽象方法;

/** 
* 制作肉馅包子 
*/
public class MakeMeatBaozi extends AbstractMakeBaozi{
    @Override
    public void selectXianLiao() {
        System.out.println("step2:选择10斤猪肉");
    }

    @Override
    public void makeXianLiao() {
        System.out.println("step3:剁猪肉馅");
    }
}

3、编写客户类Client.java,实现具体制作包子;

public class Client {    
    public static void main(String[] args) {     
        AbstractMakeBaozi meatBaozi=new MakeMeatBaozi();  
        meatBaozi.make();
        AbstractMakeBaozi eggBaozi=new MakeEggBaozi();
        eggBaozi.make();
    }
}

如何扩展

如果还想要制作韭菜鸡蛋馅的包子,需要怎么扩展呢?很简单!再定义一个制作韭菜鸡蛋馅的包子的模板实现类MakeEggBaozi.java即可:继承抽象模板类AbstractMakeBaozi.java,实现抽象模板类中的抽象方法;

提高代码复用性与可维护性:深入剖析模板方法模式_java_04

/** 
* 制作韭菜鸡蛋馅包子 
*/public class MakeEggBaozi extends AbstractMakeBaozi{    
    @Override
    public void selectXianLiao() {
        System.out.println("step2:选择鸡蛋和韭菜");
    }

    @Override
    public void makeXianLiao() {
        System.out.println("step3:剁鸡蛋和韭菜馅");
    }
}

模板方法模式的适用场景

  1. 一次性实现一个算法不变的部分,并将可变部分留给子类实现。
  2. 各个子类中,公共部分被提取出来,集中到一个公共的父类中,避免代码重复。
  3. 需要定义一个算法的骨架,并允许子类为一个或多个步骤提供实现。

模板方法模式在Spring中的应用

在Spring框架中,模板方法模式的应用主要体现在对事务的处理上。Spring框架中提供了一些模板类,如AbstractApplicationContext、AbstractApplicationContext、AbstractBeanFactory等,它们通过模板方法模式简化了对事务的处理。

当开启一个事务时,需要经过一系列的操作步骤,包括获取Session、开启事务、保存Session等。这些步骤对于不同的数据访问操作来说是相同的,因此Spring将这些公共的步骤定义为模板方法,而将具体的步骤实现留给具体的实现类来完成。

通过这种方式,Spring框架将事务处理的实现进行了抽象化和模板化,使得开发者只需要关注具体的业务逻辑实现,而不需要关注通用的步骤实现。这种方式大大简化了事务处理的复杂性,提高了代码的可重用性和可维护性。

总结

在Spring框架中,使用模板方法模式进行事务处理有以下几个好处:

  1. 简化代码:通过使用模板方法模式,可以将事务处理中公共的步骤封装到模板方法中,从而避免在具体的业务实现类中重复编写这些公共代码,大大简化了代码量。
  2. 提高可维护性:使用模板方法模式可以将事务处理的逻辑分离出来,使得业务实现类更加专注于具体的业务逻辑,这样可以使代码更加清晰易懂,提高了可维护性。
  3. 提高可重用性:使用模板方法模式可以将事务处理的逻辑抽象化,从而使得不同的业务实现类可以共享相同的事务处理逻辑,提高了代码的可重用性。
  4. 灵活性和扩展性:通过将事务处理逻辑封装到模板方法中,可以很方便地对事务处理进行扩展和修改,而不需要修改所有的业务实现类。同时,不同的业务实现类可以根据需要选择使用不同的事务处理逻辑,提高了系统的灵活性和扩展性。

总之,模板方法模式是一种行为型设计模式,它通过将算法的骨架和具体步骤的实现分离,使得子类可以方便地继承和扩展算法。以上是模板方法模式的核心角色,这种设计模式有助于在软件系统中实现开闭原则,提高代码的可复用性和可维护性。

标签:实现,子类,复用,可维护性,包子,方法,public,模板
From: https://blog.51cto.com/fanfu1024/8946984

相关文章

  • centos6和7的模板机制作
    centos6(安装操作系统直接最小化安装就行)1.进入网卡配置文件将网卡的MAC和UUID删除(网卡需要开机自启的话,只要把ONBOOT=no改为ONBOOT=yes就行)2.挂在光盘,临时挂在3.制作yum源yumcleanall#清楚yum源的缓存yummakecache#生成新的yum源yum -y install g......
  • 提高组大纲及模板
    https://www.noi.cn/upload/resources/file/2023/03/15/1fa58eac9c412e01ce3c89c761058a43.pdf数据结构线性结构【5】双端栈【5】双端队列【5】单调队列【6】优先队列【6】ST表(SparseTable)structsparseTable{ intg(intx,inty) { retu......
  • 利用Python select模块实现多路I/O复用
    在开发网络服务时,能够同时处理多个网络连接是非常重要的。传统的方法是为每个连接创建一个新线程或进程,但这在大规模时可能会导致资源耗尽。更高效的做法是使用I/O多路复用,让一个线程能够监视多个文件描述符的状态变化。在Python中,我们可以通过select模块来实现这一功能。本文将介......
  • 浅谈C++STL(Standard Template Library,标准模板库)
    2.1STL的诞生长久以来,软件界一直希望建立一种可重复利用的东西C++的面向对象和泛型编程思想,目的就是复用性的提升大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量重复工作为了建立数据结构和算法的一套标准,诞生了STL2.2STL基本概念STL(StandardTemplateLibrary,标......
  • [Halcon&定位] 解决Roi区域外的模板匹配成功
    作者:丶布布一.问题描述用halcon形状模版匹配,红色矩形框是搜索范围,ROI矩形框中间的是训练的模版,按理说应该只会匹配到ROI中中间的那个为什么会搜到搜索区域之外的部分,而且匹配分数还很高,即模板在搜索区域外仍能匹配成功。 二.原因分析使用reduce_domain裁切搜索区域部分的图像时......
  • prometheus告警记录——grafana模板
    grafana面板{"annotations":{"list":[{"builtIn":1,"datasource":{"type":"datasource","uid":"grafana"},......
  • BFS模板
    #classSolution:#defBFS(self,start,target):#q=[]#用一个列表做队列#v=[]#记录走过的路#q.append(start)#把起点放入队列#v.append(start)#加入走过的路#step=0#记录扩散步数#while......
  • 【misc】[HNCTF 2022 WEEK2]calc_jail_beginner_level4.1(JAIL) --沙盒逃逸,python模板
    这道题没给附件,直接连上看看这里一开始用().__class__.__base__.__subclasses__()[-4].__init__.__globals__[bytes([115,121,115,116,101,109]).decode()](bytes([115,104]).decode())进行尝试,后面发现bytes函数被禁用了,可以用另外的函数代替().__class__.__base__.__subclasse......
  • 一些模板
    1e12找原根板子#include<bits/stdc++.h>#definelllonglongusingnamespacestd;lln,prime[1000005],is_prime[1000005],cnt,qv[1000005],qn[1000005],top,g,Phi,sum,ans[1000005],mod;voidfj(llx){ top=0; for(lli=1;prime[i]*prime[i]<=x;i++){ if(x%pri......
  • P2197 【模板】Nim 游戏
    原题链接题解说的很详细,我来讲讲我对为什么要用异或判断的想法异或为零是先手必败状态的一个属性,我们通过属性来判断类别。代码#include<bits/stdc++.h>usingnamespacestd;intmain(){intt;cin>>t;while(t--){intn;cin>>n;......