ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

源码中的设计模式--模板方法模式(钩子方法)

2022-05-15 16:04:16  阅读:153  来源: 互联网

标签:String -- 子类 系统 校验 protected 设计模式 方法 源码


  在上次《源码中的设计模式--模板方法模式》中分享了有关模板方法设计模式方面的东西,不知道还有印象没,重温下其释义,

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重写定义算法中的某些步骤。

  在上次中举了这样的场景,要调用系统A、系统B接口,把两个系统的数据读取过来,保存在我们自己的数据库中,其实现的UML图如下,

  现在突然,系统A的对接人说,在调用他的接口前需要进行校验,验证身份,才可以进行调用。看看上面的UML图我们要怎么修改代码,我们把之前的场景抽象了四步:组装参数、发送请求、处理返回参数、保存数据库,现在系统A需要校验身份,校验这个过程是系统A独有的吗,显然不是,原则上调用任何一个系统的接口都需要验证权限,只有权限通过了才可以调用,那么校验这个肯定是上述场景中的一步,为此上面的场景抽象为五步:组装参数、校验权限、发送请求、处理返回参数、保存数据。而且校验权限这个肯定每个系统的验证方式是不一样的,所以需要每个实现类定义自己的实现,也就是它必须是一个抽象的方法

  现在还有一个实际的问题,系统A需要校验权限,系统B不需要,两个实现类均实现了校验权限的方法,岂不是都会进行校验,可不可以判断下是否需要校验,而且这个判断最好交给实现类来实现,由实现类决定是否需要校验。为此上面的UML变成了下面的样子,

  上面的UM类图有什么玄机吗,聪明的你肯定看出来了,我再絮叨絮叨。在AbastractSyncData抽象类中增加了抽象方法checkAuthority()和非抽象方法isCheckAuthority(),在SyncSystemAImpl类中实现了checkAuthority()方法和isCheckAuthority()方法,而SyncSystemBImpl仅实现了checkAuthority()方法,怎么样和我说的一样吧。

二、最新实现

下面看下现在的每个类,SyncData接口无变化,这里不再贴出,

AbstractSyncData.java

package com.example.template;

import java.util.Map;

public abstract class AbstractSyncData implements SyncData {
    //定义好同步数据的步骤
    @Override
    public void syncData() {
        //1、组装参数
        Map param = assembleParam();
        //新增步骤:判断是否需要校验权限
        if (isCheckAuthority()) {
            checkAuthority();
        }
        //2、发送请求
        String result = sendRequest(param);
        //3、解析
        String result2 = parse(result);
        //4、保存数据
        saveData(result2);
    }

    //校验权限
    protected abstract void checkAuthority();

    //是否校验权限,由该方法决定是否调用checkAuthority()方法,默认为false不校验
    protected boolean isCheckAuthority() {
        return false;
    }

    //1、组装参数,供子类实现自己的逻辑
    protected abstract Map assembleParam();

    //2、发送请求
    private String sendRequest(Map map) {
        //实际发送请求,并把数据返回
        System.out.println("发送请求");
        return "";
    }

    //3、解析返回结果,供子类实现自己的逻辑
    protected abstract String parse(String result);

    //4、保存数据
    private void saveData(String result) {
        System.out.println("保存数据");
    }
}

SyncSystemAImpl.java

package com.example.template;

import java.util.HashMap;
import java.util.Map;

public class SyncSystemAImpl extends AbstractSyncData {
    @Override
    protected void checkAuthority() {
        System.out.println("校验系统A的权限");
    }

    @Override
    protected Map assembleParam() {
        System.out.println("组装发送到系统A的参数");
        return new HashMap();
    }

    @Override
    protected String parse(String result) {
        System.out.println("解析系统A的返回结果");
        return "";
    }

    /**
     * 重写父类的方法
     *
     * @return
     */
    @Override
    protected boolean isCheckAuthority() {
        return true;
    }
}

SyncSystemBImpl.java

package com.example.template;

import java.util.HashMap;
import java.util.Map;

public class SyncSystemBImpl extends AbstractSyncData {
    @Override
    protected void checkAuthority() {
        System.out.println("校验系统B的权限");
    }

    @Override
    protected Map assembleParam() {
        System.out.println("组装发送到系统B的参数");
        return new HashMap();
    }

    @Override
    protected String parse(String result) {
        System.out.println("解析系统B的返回结果");
        return "";
    }
}

看下测试结果,

组装发送到系统A的参数
校验系统A的权限
发送请求
解析系统A的返回结果
保存数据
-----------
组装发送到系统B的参数
发送请求
解析系统B的返回结果
保存数据

Process finished with exit code 0

  从上面的结果可以看到在读取系统A的接口时多了“校验系统A的权限”,而系统B却没有,满足上面的要求。说了那么多多总算要给今天的主角正名,isCheckAuthority()方法我们称之为钩子方法。isCheckAuthority()方法在父类(抽象类)中声明,且提供了默认的实现,那么不管子类是否覆盖该方法都可以,这就是钩子方法的高明之处。

  在模板方法模式中钩子方法由抽象类声明并提供默认实现,该方法不要求子类一定去实现,所以不是抽象方法,子类可以选择@Override该方法也可以选择不这么做,如果不这么做将会使用父类的逻辑,如果这么做了则使用子类的逻辑。钩子方法要在算法的骨架中有所体现。

  有了钩子方法可以让子类有更多的自主处理逻辑的能力,在不改变算法骨架的前提下提供了更多的便利,使模板方法模式更好用。希望大家在日常的开发中多思考功能场景,尽量对问题进行抽象,从抽象中寻找共性,针对差异化的处理就可以使用“钩子方法”了。

  今天的分享就到这里,感谢你能喜欢,下次见。

 

推荐阅读

《源码中的设计模式--模板方法模式》

标签:String,--,子类,系统,校验,protected,设计模式,方法,源码
来源: https://www.cnblogs.com/teach/p/16272836.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有