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);
        }

      

      

  • 相关阅读:
    扫雷!!!!!!
    各种版本的flash player下载
    酷炫3d投影
    CodeSmith连接Access,Sql,Oracle,mysql
    处理模型——使用加速度控制速度
    处理模型——缩放模型
    处理2D图像和纹理——创建一个3D爆炸效果,简单的粒子系统
    处理模型——对不同对象设置不同的世界矩阵,组合世界矩阵
    处理模型——使用BasicEffect类载入模型
    处理模型——使用自定义Effects和纹理绘制模型
  • 原文地址:https://www.cnblogs.com/l3306/p/10763305.html
Copyright © 2011-2022 走看看