设计模式 - 应用场景:模板方法模式 + 策略模式 + Lambda

Posted 笑虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式 - 应用场景:模板方法模式 + 策略模式 + Lambda相关的知识,希望对你有一定的参考价值。

设计模式 - 应用场景:模板方法模式 + 策略模式 + Lambda

package com.jerry.enums;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONObject;
import com.jerry.dto.SaveDTO;

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;

/**
 * 业务类型枚举
 * 1. 通过 key 判断类型,
 * 【平台A】的 JSON 反序列化为 TsDTO、JbDTO、ZxDTO、ByDTO 
 * 再复制为【平台B】的 SaveDTO。
 * 2. 包含每种类型的转换策略
 */
public enum TEMPLATE_ENUM 
    /** 业务类型-ts */
    TS("ts", TsDTO.class, (TsDTO tsDTO) -> 
        // 处理诉求内容:  "zz": "重做", "gh": "更换", "xl": "修理"  转为 "重做,更换修理"
        String appRequest = tsDTO.getAppRequest();
        tsDTO.setAppRequest(appRequest.replaceAll("[:\\"a-zA-Z0-9]", ""));
        return tsDTO;
    ),
    /** 业务类型-jb */
    JB("jb", JbDTO.class, Function.identity()),
    /** 业务类型-zx */
    ZX("zx", ZxDTO.class, Function.identity()),
    /** 业务类型-by */
    BY("by", ByDTO.class, Function.identity()),
    /** 找不到对应策略时,可以用这个返回 null */
    DEFAULT("default", null, Function.identity());
    
    private String key;
    private Class clazz;
    private Function strategy;

    /**
     * @param key       对应【平台A】的 key
     * @param clazz     原DTO类型:A、B、C、D
     * @param strategy  将业务数据从【平台A】转到【平台B】的策略
     */
    TEMPLATE_ENUM(String key, Class clazz, Function<?, ?> strategy) 
        this.key = key;
        this.clazz = clazz;
        this.strategy = strategy;
    
    
    /**
     * 通过 key 获取对应业务的处理策略 action
     * 
     * 【原DTO】与【目标DTO】属性完全相同。
     * 【原DTO】有多种,通过添加 @JSONField 与【平台A】对应。
     *  json 反序列化为各种【原DTO】
     * 【原DTO】通过属性拷贝,创建【目标DTO】
     * 
     * @param key   对应【平台A】的 key
     * @return
     */
    public static Function<JSONObject, SaveDTO> getByKey(String key)
        // 取出所有 value
        TEMPLATE_ENUM[] values = TEMPLATE_ENUM.values();
        // 遍历找到目标 key 返回枚举对象
        Optional<TEMPLATE_ENUM> first = Arrays.stream(values).filter(bt -> bt.key.equals(key)).findFirst();
        // 如果没有找到就返回 DEFAULT 它的策略是始终返回结果 null
        TEMPLATE_ENUM tempEnum = first.orElse(DEFAULT);
        // 模板方法
        return (JSONObject jsonObject) -> 
            Object temp = jsonObject.to(tempEnum.clazz);
            temp = tempEnum.strategy.apply(temp); // key 取出来的具体策略
            return BeanUtil.copyProperties(temp, SaveDTO.class, "");
        ;
    
    


这里其实使用 UnaryOperatorFunction 更合适,但我偷懒写完后就懒得动了。反正UnaryOperator<T> 的底层就是 Function<T, T>

以上是关于设计模式 - 应用场景:模板方法模式 + 策略模式 + Lambda的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之模板方法模式和策略模式

策略模式应用场景

java策略模式应用场景为何?

java设计模式7.策略模式模板方法模式观察者模式

spring中如何使用策略模式

MVVM模式在iOS中常用场景