互联网架构-精讲设计模式-003:模板方法模式

1 工厂模式简单的介绍

课程内容:
1.什么是工厂模式
2.什么场景使用工厂模式
3.工厂模式类型的分类
4.什么是模板方法设计模式
5.模板方法设计模式应用场景
6.基于工厂+模板方法实现异步回调重构
7.Servlet模板方法设计模式源码分析

工厂模式
工厂模式是为了解耦,把对象的创建和使用的过程分开。就是Class A想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类。
工厂模式可以分为简单工厂、工厂方法、抽象工厂、静态工厂模式

2 静态工厂的使用介绍

在这里插入图片描述

@Component
public interface PaymentService {

    public void pay();
}

public class AliPaySercice implements PaymentService {
    @Override
    public void pay() {
        System.out.println("阿里支付对象...");
    }
}

public class WeChatService implements PaymentService {
    @Override
    public void pay() {
        System.out.println("微信支付对象...");
    }
}

class PayMentFactory {
    public static PaymentService getPaymentService(String payType) {
        PaymentService paymentService = null;
        switch (payType) {
            case "ali_pay":
                paymentService = new AliPaySercice();
                break;
            case "wechat_pay":
                paymentService = new WeChatService();
                break;
        }
        return paymentService;
    }
} 

public class Test {
    public static void main(String[] args) {

        PaymentService aliPay = PaymentFactory.getPaymentService("ali_pay");
        PaymentService weChatPay = PaymentFactory.getPaymentService("wechat_pay");
        aliPay.pay();
        weChatPay.pay();
    }
}

在这里插入图片描述

3 Spring框架源码工厂的使用

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
工厂模式优缺点
优点:
代码结构简单。
获取产品的过程更加简单。
满足了开闭原则,即对拓展开放,对修改关闭。
缺点
拓展较繁琐,要拓展时,需同时改动抽象工厂和工厂实现类。

4 模板方法设计模式简单介绍

模板模式
什么是模板方法

定义了一个操作中算法的整体骨架,而将部分步骤的实现在子类中完成。
相同的行为定义在抽象方法中,不同行为的实现就定义在子类中实现。
重复代码抽取到父类里面,不同业务的具体的实现交给子类进行处理。

核心设计要点:
AbstractClass: 抽象类,定义并实现一个模板方法。这个模板方法定义了算法的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类去实现
ConcreteClass: 实现父类所定义的一个或多个抽象方法。

模板方法应用场景

  1. 比如聚合支付平台中系统回调代码重构
  2. Servlet 请求
    在这里插入图片描述

参数不同、行为相同指的是什么?
都是解析回调通知报文,再修改支付状态为已成功。
异步回调流程:

  1. 解析报文(验证签名)
  2. 日志收集(相同)
  3. 如果解析报文成功的话,修改支付状态为已成功(相同),返回不同的支付结果。

5 定义模板方法设计模式共同骨架

AbstractPayCallbackTemplate

@Slf4j
public abstract class AbstractPayCallbackTemplate {

    /**
     * 定义共同行为的骨架
     * @return
     */
    public String asyncCallBack(){
        // 1.验证参数和验证签名
        Map<String, String> verifySignature = verifySignature();
        // 2.日志收集 相同
        payLog(verifySignature);
        // 3.获取验证签名状态
        String analysisCode = verifySignature.get("analysisCode");
        if(!analysisCode.equals("200")){
            return resultFail();
        }
        // 4.更改数据库状态同时返回不同支付结果
        return asyncService(verifySignature);
    }

    /**
     * 验证参数..
     * @return
     */
    protected abstract Map<String, String> verifySignature();

    /**
     * 使用多线程异步写入日志
     * @param verifySignature
     */
    @Async
    public void payLog(Map<String, String> verifySignature) {
        log.info(">>>>>第二步 写入数据库...verifySignature:{}", verifySignature);
    }

    /**
     * 执行修改订单状态和返回不同的结果
     * @param verifySignature
     * @return
     */
    protected abstract String asyncService(Map<String, String> verifySignature);

    /**
     * 返回失败结果
     * @return
     */
    protected abstract String resultFail();

    /**
     * 返回成功的结果
     * @return
     */
    protected abstract String resultSuccess();
}

6 模板方法设计模式具体的实现

AliPayCallbackTemplate/UnionPayCallbackTemplate

@Component
@Slf4j
public class AliPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设一下为AliPay回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 解析支付宝报文.....verifySignature()");
        Map<String, String> verifySignature = new HashMap<>();
        verifySignature.put("price", "1399");
        verifySignature.put("orderDes", "充值蚂蚁课堂永久会员");
        // 支付状态为1表示为成功....
        verifySignature.put("aliPayMentStatus", "1");
        verifySignature.put("aliPayOrderNumber", "201910101011");
        // AliPay回调报文处理结束..

        // 解析报文是否成功 或者验证签名成功返回 200 为成功..
        verifySignature.put("analysisCode", "200");
        return verifySignature;
    }

    @Override
    protected String asyncService(Map<String, String> 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 resultFail() {
        return "fail";
    }

    @Override
    protected String resultSuccess() {
        return "success";
    }

}
@Component
@Slf4j
public class UnionPayCallbackTemplate extends AbstractPayCallbackTemplate {
    @Override
    protected Map<String, String> verifySignature() {
        //>>>>假设以下为银联回调报文>>>>>>>>>>>>>>>>
        log.info(">>>>>第一步 解析银联数据报文.....verifySignature()");
        Map<String, String> 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<String, String> 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 resultFail() {
        return "fail";
    }

    @Override
    protected String resultSuccess() {
        return "ok";
    }
}

7 使用工厂模式获取具体实现模板

TemplateFactory

public class TemplateFactory {

    /**
     * 使用工厂模式获取模板
     * @param templateId
     * @return
     */
    public static AbstractPayCallbackTemplate getPayCallbackTemplate(String templateId) {
        AbstractPayCallbackTemplate payCallbackTemplate = (AbstractPayCallbackTemplate) SpringUtils.getBean(templateId);
        return payCallbackTemplate;
    }
}

Controller

@RestController
public class TemplateController {

    /**
     * 支付回调
     * @return
     */
    @RequestMapping("/asyncCallback")
    public String asyncCallback(String templateId) {
        AbstractPayCallbackTemplate payCallbackTemplate = TemplateFactory.getPayCallbackTemplate(templateId);
        // 使用模板方法模式 执行共同的骨架
        return payCallbackTemplate.asyncCallBack();
    }
}

启动类 AppTemplate

@SpringBootApplication
@EnableAsync
public class AppTemplate {
    public static void main(String[] args) {
        SpringApplication.run(AppTemplate.class);
    }
}

在这里插入图片描述

8 模板方法与策略模式的区别

模式模式优缺点
1)优点
模板方法模式通过把不变的行为搬移到父类,去除了子类中的重复代码。子类实现算法的某些细节,有助于算法的扩展。通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
2)缺点
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
3)适用场景
在某些类的算法中,用了相同的方法,造成代码的重复。控制子类扩展,子类必须遵守相同的算法规则。

策略模式与模板方法模式的区别?
策略模式整体骨架都是不同的,主要针对多重if分支的细节;
模板方法解决整体骨架,相同的行为放在抽象类中实现,不同的行为放子类中实现。

9 servlet底层模板方法的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值