zoukankan      html  css  js  c++  java
  • 使用策略模式改造代码坏味道,让代码更有质量

    一、适用场景

      在日常的代码开发过程中,你是否频繁的适用if/else、if elseif else 等这种语句,有没有想过使用设计模式来改造你的代码,让你的代码更加有质量。

      我们在开发过程中,很常见的会遇到,不同角色对资源进行不同的分配,例如:不同的用户身份(vip、svip、normal)面临不同的计价策略。

      此时面对这样的场景:

        这种计价策略属于平级状态,每次根据用户的身份只会选择一种计价策略。

      未使用策略模式前的代码:

    import com.shuwen.demo.service.FeeCalculationService;
    import org.springframework.stereotype.Service;
    
    
    @Service
    public class FeeCalculationsServiceImpl implements FeeCalculationService {
    
        @Override
        public double feeCalculation(String type, double fee) {
            if ("vip".equals(type)){
                return fee * 0.98;
            }else if ("svip".equals(type)){
                return fee * 0.90;
            }else{
                return fee ;
            }
        }
    }
    

       发现当我们需要对其进行扩展时,只能对原来的代码进行添加,在原来的代码上修改代码,这就是代码中的坏味道。


       我们需要去除这种代码中的坏味道,让代码清新起来,让代码的可拓展性更强,便于项目的维护和二次开发。

       现在我们将其进行改造:

        a)定义策略接口 规范策略必有内容

    public interface DiscountStrategy {
      //角色类型 public String type();
      //计价策略 public double discount(double fee); }

        b)实现策略接口,编写具体的实现业务

          1)VIP用户计价策略的具体实现

    import com.shuwen.demo.strategy.DiscountStrategy;
    import org.springframework.stereotype.Service;
    
    @Service
    public class VipDiscountStrategy implements DiscountStrategy {
        @Override
        public String type() {
            return "vip";
        }
    
        @Override
        public double discount(double fee) {
            return fee * 0.98;
        }
    }
    

          2)SVIP用户计价策略的具体实现

    import com.shuwen.demo.strategy.DiscountStrategy;
    import org.springframework.stereotype.Service;
    
    @Service
    public class SvipDiscountStrategy implements DiscountStrategy {
        @Override
        public String type() {
            return "svip";
        }
    
        @Override
        public double discount(double fee) {
            return fee * 0.70;
        }
    }
    

          3)普通用户计价策略的具体实现

    import com.shuwen.demo.strategy.DiscountStrategy;
    import org.springframework.stereotype.Service;
    
    @Service
    public class NormalDiscountStrategy implements DiscountStrategy {
        @Override
        public String type() {
            return "normal";
        }
    
        @Override
        public double discount(double fee) {
            return fee;
        }
    }
    

        c)将具体的策略方法,存放到map之中,方便使用

      //用map来存策略方法
        Map<String,DiscountStrategy> discountStrategyMap = new HashMap<>();
        //利用构造方法 将策略方法放到map中 此处List<DiscountStrategy> spring将自动注入策略
        public FeeCalculationServiceImpl(List<DiscountStrategy> discountStrategies) {
            for (DiscountStrategy discountStrategy : discountStrategies){
                discountStrategyMap.put(discountStrategy.type(),discountStrategy);
            }
        }
    

        d)具体的业务实现,就变的可拓展性极强。

    import com.shuwen.demo.service.FeeCalculationService;
    import com.shuwen.demo.strategy.DiscountStrategy;
    import org.springframework.stereotype.Service;
    
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Service
    public class FeeCalculationServiceImpl implements FeeCalculationService {
        //用map来存策略方法
        Map<String,DiscountStrategy> discountStrategyMap = new HashMap<>();
        //利用构造方法 将策略方法放到map中 此处List<DiscountStrategy> spring将自动注入策略
        public FeeCalculationServiceImpl(List<DiscountStrategy> discountStrategies) {
            for (DiscountStrategy discountStrategy : discountStrategies){
                discountStrategyMap.put(discountStrategy.type(),discountStrategy);
            }
        }
    
        @Override
        public double feeCalculation(String type, double fee) {
            // 只需利用map 用key:type 找到对应的具体策略方法,直接使用即可
            // 如有需求改变,有新的用户身份 直接实现策略接口 并交由spring工厂管理即可
            DiscountStrategy discountStrategy = discountStrategyMap.get(type);
            double discount = discountStrategy.discount(fee);
            return discount;
        }
    }
    

       这样来实现业务代码,泛泛而看是去掉了很多if else 条件判断,这样当我们的需求发生变化时,只需新增一个具体的策略方法即可。

       例如现在有一个新需求,黑卡用户需要打0.5折:

        这时,我们只需要增加一个黑卡用户的计价具体策略方法即可,不需要变更原来的业务处理方法。

    import com.shuwen.demo.strategy.DiscountStrategy;
    import org.springframework.stereotype.Service;
    
    @Service
    public class HVipDiscountStrategy implements DiscountStrategy {
        @Override
        public String type() {
            return "hvip";
        }
    
        @Override
        public double discount(double fee) {
            return fee * 0.50;
        }
    }
    

      这时,我们的代码质量大大改善,以后维护也更加轻松~

      测试调用方法具体实现:

    @Test
        public void test1() {
            double vip = feeCalculationService.feeCalculation("vip", 5000);
            System.out.println("yesterday you have consumer 5000 dollars,true you have consumer "+vip);
        }

      

      

  • 相关阅读:
    HDU3440 House Man (差分约束)
    POJ1201 Intervals (差分约束)
    POJ2154 Color【 polya定理+欧拉函数优化】(三个例题)
    【2018年全国多校算法寒假训练营练习比赛(第三场)】
    数据人看Feed流-架构实践
    开源背后 | 面对端侧推理引擎的挑战,阿里工程师如何应对?
    容器十年 ——一部软件交付编年史
    公网对讲行业大咖分享:铁通电子为何选择阿里云?
    逾期率飙升如何破?揭秘金融科技如何化解消费金融行业风险
    微服务开源生态报告 No.2
  • 原文地址:https://www.cnblogs.com/l3306/p/10763305.html
Copyright © 2011-2022 走看看