当前位置:

首页 > 编程开发 > Java设计模式之模板方法实例分析

Java设计模式之模板方法实例分析

概念模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系。因此,在模板方法模式的类结构图中,只有继承关系。核心设计要点AbstractClass:抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现。ConcreteClass:实现实现父类所定义的一个或多个抽象方法。优缺点优点利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高

本文目录

    概念

    模板方法模式是所有模式中最为常见的几个模式之一,是基于继承的代码复用的基本技术,没有关联关系。因此,在模板方法模式的类结构图中,只有继承关系。

    核心设计要点

    AbstractClass:抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现。

    ConcreteClass:实现实现父类所定义的一个或多个抽象方法。

    优缺点

    优点

    • 利用模板方法将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。

    • 将不同的代码不同的子类中,通过对子类的扩展增加新的行为,提高代码的扩展性。

    • 把不变的行为写在父类.上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。

    缺点

    类数目的增加,每一个抽象类都需要一个子类来实现,这样导致类的个数增加,复杂性增加。类数量的增加,间接地增加了系统实现的复杂度。继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一-遍。

    应用场景

    • 父类视角:一次性实现一个算法不变的部分,并将可变部分留给子类实现;

    • 子类视角:各个子类中,公共部分被提取出来,集中到一个公共的父类中,避免代码重复;

    模板方法模式的目的是让子类可以扩展或具体实现固定方法的某个具体的步骤;对于模板来说,是一套固定的算法 ,通过子类可以扩展固定算法中某些算法步骤。

    模板方法和策略模式的区别

    策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换。还有一种模

    式也是关注对算法的封装一模版方法模式,对照类图可以看到,策略模式与模版方法模式的区别仅仅是多了一个单独的封装类

    Context,它与模版方法模式的区别在于:在模版方法模式中,调用算法的主体在抽象的父类中,而在策略模式中,调用算法的主

    体则是封装到了封装类Context中,抽象策略Strategy一般是一个接口, 目的只是为了定义规范,里面一般不包含逻辑。其实,这只是通用实现,而在实际编程中,因为各个具体策略实现类之间难免存在–些相同的逻辑,为了避免重复的代码,我们常常使用抽象类来担任Strategy的角色,在里面封装公共的代码,因此,在很多应用的场景中,在策略模式中- -般会看到模版方法模式的影子。

    代码案例

    模版方法抽象类

    @Slf4j
    public abstract class AbstractPayCallbackTemplate {
        /**
         * 异步回调业务
         *
         * @return
         */
        public String asyncCallBack() {
            // 1. 支付回调验证参数
            Map verifySignatureMap = verifySignature();
            // 2. 参数验证成功,写入日志中..
            payLog(verifySignatureMap);
            String analysisCode = verifySignatureMap.get("analysisCode");
            if (!analysisCode.equals("200")) {
                return resultFail();
            }
            // 3. 执行回调异步相关逻辑
            return asyncService(verifySignatureMap);
        }
        /**
         * 支付回调验证参数
         *
         * @return
         */
        protected abstract Map verifySignature();
        /**
         * 使用多线程异步写入日志
         *
         * @param verifySignatureMap
         */
        @Async
        void payLog(Map verifySignatureMap) {
            log.info(">>>>>>>>>>第二步 写入payLog........");
        }
        /**
         * 每个子类需要实现 实现业务解析操作
         *
         * @return
         */
        protected abstract String asyncService(Map verifySignatureMap);
        /**
         * 异步返回结果..
         *
         * @return
         */
        protected abstract String resultSuccess();
        /**
         * 异步返回失败
         *
         * @return
         */
        protected abstract String resultFail();
    }

    具体实现模版类

    @Log4j2
    public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
        @Override
        protected Map verifySignature() {
            //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
            log.info(">>>>>第一步 解析支付宝据报文.....verifySignature()");
            Map verifySignature = new HashMap<>();
            verifySignature.put("price", "1399");
            verifySignature.put("orderDes", "充值永久会员");
            // 支付状态为1表示为成功....
            verifySignature.put("aliPayMentStatus", "1");
            verifySignature.put("aliPayOrderNumber", "201910101011");
            // 解析报文是否成功 200 为成功..
            verifySignature.put("analysisCode", "200");
            return verifySignature;
        }
        @Override
        protected String asyncService(Map verifySignatureMap) {
            log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
            String paymentStatus = verifySignatureMap.get("aliPayMentStatus");
            if (paymentStatus.equals("1")) {
                String aliPayOrderNumber = verifySignatureMap.get("aliPayOrderNumber");
                log.info(">>>>orderNumber:{aliPayOrderNumber},已经支付成功 修改订单状态为已经支付...");
            }
            return resultSuccess();
        }
        @Override
        protected String resultSuccess() {
            return "ok";
        }
        @Override
        protected String resultFail() {
            return "fail";
        }
    }
    @Slf4j
    public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
        @Override
        protected Map verifySignature() {
            //>>>>假设一下为银联回调报文>>>>>>>>>>>>>>>>
            log.info(">>>>>第一步 解析银联数据报文.....verifySignature()");
            Map verifySignature = new HashMap<>();
            verifySignature.put("price", "1399");
            verifySignature.put("orderDes", "充值永久会员");
            // 支付状态为1表示为成功....
            verifySignature.put("paymentStatus", "1");
            verifySignature.put("orderNumber", "201910101011");
            // 解析报文是否成功 200 为成功..
            verifySignature.put("analysisCode", "200");
            return verifySignature;
        }
        @Override
        protected String asyncService(Map verifySignatureMap) {
            log.info(">>>>>第三步asyncService()verifySignatureMap:{}", verifySignatureMap);
            String paymentStatus = verifySignatureMap.get("paymentStatus");
            if (paymentStatus.equals("1")) {
                String orderNumber = verifySignatureMap.get("orderNumber");
                log.info(">>>>orderNumber:{orderNumber},已经支付成功 修改订单状态为已经支付...");
            }
            return resultSuccess();
        }
        @Override
        protected String resultSuccess() {
            return "success";
        }
        @Override
        protected String resultFail() {
            return "fail";
        }
    }

    工厂模式获取模版

    public class TemplateFactory {
        private final static Map templateMap = new ConcurrentHashMap<>();
        static {
            templateMap.put("aliPay", new AliPayCallbackTemplate());
            templateMap.put("unionPay", new UnionPayCallbackTemplate());
        }
        public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
            AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) templateMap.get(templateId);
            return payCallbackTemplate;
        }
    }

    测试类

    public class Test {
        public static void main(String[] args) {
            AbstractPayCallbackTemplate aliPay = TemplateFactory.getPayCallbackTemplate("aliPay");
            String s = aliPay.asyncCallBack();
            System.out.println(s);
        }
    }
    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。