IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 设计模式之模板模式 -> 正文阅读

[PHP知识库]设计模式之模板模式

设计模式之模板模式

定义: 定义一个操作的算法骨架,而将一些步骤延迟到子类中。Template method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

应用场景:

  • 当你想让客户端只扩展算法的特定步骤时,而不是整个算法或其结构时
  • 当你有几个类包含几乎形同的算法,但有一些细微的差异时

优点:

  • 你可以让客户端只覆盖大型算法的某些部分,从而减少算法其他部分发生的更改对他们的影响
  • 你可以将重复的代码拖放到超类中

可以参考:

  • javax.servlet.http.HttpServlet
  • org.springframework.web.servlet.mvc.AbstractController

今天我们说下模板模式在实际项目中使用的场景之一,话补多少直接上代码

/**
 * 定义下我们的主体代码
 */
@Slf4j
@Service
public abstract class AbstractPayPatternService {

    /**
     * 实际支付方法
     * @param orderNo
     * @param pattern
     * @return
     */
    public String doPay(String orderNo, String pattern) {
        //1.根据订单号  获取订单相关信息

        //2.验证参数  传入订单对象验证相关参数
        checkData(null);
        //3.支付前参数组装,返回相关的map组装信息  入参是订单相关参数
        Map<String,Object> map = verifySignature(null);
        //4.执行对相应的支付方式 service
        String result = executeService(map);
        //5.异步部写入操作日志
        writeLog(null);
        return "SUCCESS";
    }

    /**
     * 支付时 参数校验
     * @param object
     * @return
     */
    public void checkData(Object object){
        log.info("参数验证");
    }

    /**
     * 写入操作日志
     * @param object
     */
    public final void writeLog(Object object){
        log.info("异步写入操作日志信息");
    }

    /**
     * 支付前  参数准备
     * @param object
     * @return
     */
    protected abstract Map<String,Object> verifySignature(Object object);

    /**
     * 业务执行
     * @param map
     * @return
     */
    protected abstract String executeService(Map<String,Object> map);
}

现在我们去编写相关业务的执行代码,这里实现 InitializingBean 主要是想换一种方式标记当前类,当然你也可以使用@Service(“XXXXX”)来标记当类的唯一标识,这里只做一个实现类,如果其他的支付方式 可以自己另行创建实现

/**
 * @author lgl
 * @date 2021/9/1
 */
@Slf4j
@Service
public class WechatPayServiceImpl extends AbstractPayPatternService implements InitializingBean {

    @Override
    protected Map<String, Object> verifySignature(Object object) {
        log.info("微信方支付参数认证和签名");
        return new HashMap<>(0);
    }

    @Override
    protected String executeService(Map<String, Object> map) {
        log.info("微信支付接口调用和业务处理");
        return "OK";
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        SpringUtil.STATE_MAP.put("wechatPay","wechatPayServiceImpl");
    }
}
/**
 * @author lgl
 * @date 2021/8/31
 */
@Slf4j
@Component
public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext context;

    /**
     * 状态与类名的映射
     */
    public static Map<String,String> STATE_MAP = new HashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringUtil.context = applicationContext;
    }

    /**
     * 获取上下文对象
     * @return
     */
    public static ApplicationContext getContext(){
        return context;
    }

    /**
     * 根据name获取对象bean
     * @param name
     * @return
     */
    public static Object getBean(String name){
        return getContext().getBean(name);
    }

    /**
     * 根据class获取对象bean
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz){
        return getContext().getBean(clazz);
    }

    /**
     * 根据name 以及对象指定返回bean
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name,Class<T> clazz){
        //改造前: name是之具体的类名
        //改造后:name为状态映射类名  这样前端直接传具体的状体就可以了  也可以把该参数维护成枚举
        String clsName = STATE_MAP.get(name);
        return getContext().getBean(clsName,clazz);
    }
}

```java
/**
 * 其中pattern可以是你实现类的唯一标识  或者是映射后的参数 当然也可以使用枚举类做标识映射
 * @author lgl
 * @date 2021/9/1
 */
@RestController
@RequestMapping("pay")
public class PayPatternController {

    @GetMapping("pay")
    public String payOrder(String payPattern){
        AbstractPayPatternService bean = SpringUtil.getBean(payPattern, AbstractPayPatternService.class);
        String result = bean.doPay("O9876", payPattern);
        return result;
    }
}

标记类方法 也可以参考上一篇的状态模式篇 小编尽量在以后的创作中使用不同的实现方式

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 18:34:35  更:2021-09-11 18:36:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:25:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码