战狂粗人张

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、需求

根据优惠券的类型resourceType 查询 发放方式grantType和领取规则。

 

二、简单实现

采用switch case 方式。

缺点:后期代码难以维护,可读性不强。

package cn.zwx.strategy.pattern.example.simple;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

/**
 * @projectName:strategy-pattern-example
 * @see:cn.zwx.strategy.pattern.example.simple
 * @author:zhangwenxue
 * @createTime:2022/2/11 10:08
 * @version:1.0
 */
@Service
public class SimpleService {

    private Logger logger = LoggerFactory.getLogger(SimpleService.class);

    /**
     *  模拟查询派发业务
     * @return java.lang.String
     * @author zhangwenxue
     * @createTime 2022/2/11 10:15
     * @thorws
     **/
    public String getResult(String resourceName) {
        switch(resourceName){
            case "红包":
                //查询红包的派发方式
                return "每周末9点发放";
            case "购物券":
                //购物券的发放方式
                return "每周三9点发放";
            case "QQ会员" :
                //qq会员的发放方式
                return "每周一0点开始秒杀";
            case "外卖会员" :
                //外卖会员发放方式
                return "每周四八点开始秒杀";
            default :
                logger.info("查找不到该优惠券类型resourceType以及对应的派发方式");
                return "查找不到该优惠券类型resourceType以及对应的派发方式";
        }
    }
}

 

三、策略方式实现

优点:维护性得到提高。

缺点:

如果 if-else的判断情况很多,那么对应的具体策略实现类也会很多,上边的具体的策略实现类还只是2个,查询红包发放方式写在类RedPaper里边,购物券写在另一个类Shopping里边;

那资源类型多个QQ会员和外卖会员,不就得再多写两个类?有点麻烦了没法俯视整个分派的业务逻辑。

package cn.zwx.strategy.pattern.example.basic;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 优惠券核心逻辑
 * @see:cn.zwx.strategy.pattern.example.basic
 * @author:zhangwenxue
 * @createTime:2022/2/11 10:19
 * @version:1.0
 */
public interface GrantTypeStrategy {

    Map<String,GrantTypeStrategy> GRANT_TYPE_STRATEGY_MAP = new ConcurrentHashMap<>(8);

    /**
     *  初始化方法
     * @author zhangwenxue
     * @createTime 2022/2/11 10:21
     **/
    @PostConstruct
    default void init(){
        GRANT_TYPE_STRATEGY_MAP.put(getGrantType(),this);
    }

    /**
     *  获取优惠券类型
     * @return java.lang.String
     * @author zhangwenxue
     * @createTime 2022/2/11 10:22
     **/
    String getGrantType();


    /**
     *  查询方法
     * @return java.lang.String
     * @author zhangwenxue
     * @createTime 2022/2/11 10:24
     **/
    String query();
}
package cn.zwx.strategy.pattern.example.basic;

import org.springframework.stereotype.Component;

/**
 * 对应子类实现
 * @see:cn.zwx.strategy.pattern.example.basic
 * @author:zhangwenxue
 * @createTime:2022/2/11 10:25
 * @version:1.0
 */
@Component
public class GrantTypeStrategyForQqVip implements GrantTypeStrategy {
    @Override
    public String getGrantType() {
        return "QQ会员";
    }

    @Override
    public String query() {
        return "每周一0点开始秒杀";
    }
}
package cn.zwx.strategy.pattern.example.basic;

import org.springframework.stereotype.Service;

import java.util.Objects;

import static cn.zwx.strategy.pattern.example.basic.GrantTypeStrategy.GRANT_TYPE_STRATEGY_MAP;

/**
 * @projectName:strategy-pattern-example
 * @see:cn.zwx.strategy.pattern.example.basic
 * @author:zhangwenxue
 * @createTime:2022/2/11 10:18
 * @version:1.0
 */
@Service
public class BasicService {

    /**
     *  策略模式 虽然解决了if-else的问题 但是也暴露出
     *  对应的类增多的问题 虽然比switch case 易于维护但是不够优雅
     * @param resourceName xxx
     * @return java.lang.String
     * @author zhangwenxue
     * @createTime 2022/2/11 10:28
     **/
    public String getResult(String resourceName) {
        GrantTypeStrategy grantTypeStrategy = GRANT_TYPE_STRATEGY_MAP.get(resourceName);
        if (Objects.isNull(grantTypeStrategy)){
           return "查找不到该优惠券类型resourceType以及对应的派发方式";
        }
        return grantTypeStrategy.query();
    }
}

 

四、函数式编程

Map+函数式接口通过Map.get(key)来代替 if-else的业务分派,能够避免策略模式带来的类增多、难以俯视整个业务逻辑的问题。

package cn.zwx.strategy.pattern.example.strategy;

import org.springframework.stereotype.Service;

/**
 * 查询优惠方式处理类
 * @author 105286
 */
@Service
public class GrantTypeService {

    String redPaper() {
        return "每周末9点发放";
    }

    String shopping() {
        return "每周三9点发放";
    }

    String qqVip() {
        return "每周一0点开始秒杀";
    }

    String takeOutVip() {
        return "每周四八点开始秒杀";
    }
}
package cn.zwx.strategy.pattern.example.strategy;

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;


/**
 * @projectName:strategy-pattern-example
 * @see:cn.zwx.strategy.pattern.example.strategy
 * @author:zhangwenxue
 * @createTime:2022/2/11 10:31
 * @version:1.0
 */
@Service
public class StrategyService {

    @Resource
    private GrantTypeService grantTypeService;

    private Map<String, Function<String,String>> grantTypeMap =new ConcurrentHashMap<>(8);

    /**
     *  初始化业务分派逻辑,代替了if-else部分
     *  key: 优惠券类型
     *  value: lambda表达式,最终会获得该优惠券的发放方式
     */
    @PostConstruct
    public void dispatcherInit(){
        grantTypeMap.put("红包",resourceType->grantTypeService.redPaper());
        grantTypeMap.put("购物券",resourceType->grantTypeService.shopping());
        grantTypeMap.put("QQ会员",resourceType->grantTypeService.qqVip());
        grantTypeMap.put("外卖会员",resourceType->grantTypeService.takeOutVip());
    }

    public String getResult(String resourceType){
        Function<String,String> result = grantTypeMap.get(resourceType);
        if(Objects.nonNull(result)){
            return result.apply(resourceType);
        }
        return "查询不到该优惠券的发放方式";
    }

}

 

posted on 2022-06-02 11:41  战狂粗人张  阅读(93)  评论(0编辑  收藏  举报