• java设计模式之策略


    策略模式是指根据不同的对象,来采取不同的策略,其实这种场景非常场景。

    促销活动中的打折就是最常见的一张。我们会根据这个客户的类型、或者他参与的活动的类型,或者是购物金额的不同采用不同的打折策略。

    首先我们定义一个策略接口类

    public interface Strategy {
        Double discount(Double Double);
    }
    
    //普通用户打折策略
    public class CommonStrategy implements Strategy {
        @Override
        public Double discount(Double amount) {
            return amount;
        }
    }
    
    //会员用户打折策略
    public class MemberStrategy implements Strategy {
        @Override
        public Double discount(Double amount) {
            return 0.9 * amount;
        }
    }
    
    //vip用户打折策略
    public class VipStrategy implements Strategy {
        @Override
        public Double discount(Double amount) {
            return 0.8 * amount;
        }
    }

    用户类型的枚举类

    public enum  CustomerEnum {
        COMMON,MEMBER,VIP;
    }

    我们定义一个工厂类,根据用户类型返回不同的策略

    public class StrategyFactory {
    
        private static Map<CustomerEnum, Strategy> map = new ConcurrentHashMap<>();
    
        static {
            map.put(CustomerEnum.COMMON, new CommonStrategy());
            map.put(CustomerEnum.MEMBER, new MemberStrategy());
            map.put(CustomerEnum.VIP, new VipStrategy());
        }
    
        /**
         * 这样只不过把业务逻辑中的if/else挪到了工厂类中
         *
         * @param userType
         * @return
         */
        public static Strategy getStrategy(CustomerEnum userType) {
            Strategy strategy;
            if (userType == CustomerEnum.COMMON) {
                strategy = new CommonStrategy();
            } else if (userType == CustomerEnum.MEMBER) {
                strategy = new MemberStrategy();
            } else {
                strategy = new VipStrategy();
            }
            return strategy;
        }
    
        /**
         * 通过map构造一张哈希表,将类型和策略映射起来,减少if/else和switch的出现
         * @param userType
         * @return
         */
        public static Strategy getStrategyByType(CustomerEnum userType) {
            return map.get(userType);
        }
    }

    订单类和入口类

    @Data
    public class Order {
        private CustomerEnum userType;
        private double amount;
    }
    
    //入口类
    public class Application {
        public static void main(String[] args) {
            Order order = new Order();
            order.setAmount(10000.0);
            order.setUserType(CustomerEnum.VIP);
            Strategy strategy = StrategyFactory.getStrategy(order.getUserType());
            double payAmount= strategy.discount(order.getAmount());
            System.out.println(payAmount);
        }
    }

    可能有人问,如果我的if/else里不是类型,而是区间范围怎么办,也是可以解决的,看下面代码

    public class Sorter {
      private static final long GB = 1000 * 1000 * 1000;
      private static final List<AlgRange> algs = new ArrayList<>();
      static {
        algs.add(new AlgRange(0, 6*GB, SortAlgFactory.getSortAlg("QuickSort")));
        algs.add(new AlgRange(6*GB, 10*GB, SortAlgFactory.getSortAlg("ExternalSort")));
        algs.add(new AlgRange(10*GB, 100*GB, SortAlgFactory.getSortAlg("ConcurrentExternalSort")));
        algs.add(new AlgRange(100*GB, Long.MAX_VALUE, SortAlgFactory.getSortAlg("MapReduceSort")));
      }
    
      public void sortFile(String filePath) {
        // 省略校验逻辑
        File file = new File(filePath);
        long fileSize = file.length();
        ISortAlg sortAlg = null;
        for (AlgRange algRange : algs) {
          if (algRange.inRange(fileSize)) {
            sortAlg = algRange.getAlg();
            break;
          }
        }
        sortAlg.sort(filePath);
      }
    
      private static class AlgRange {
        private long start;
        private long end;
        private ISortAlg alg;
    
        public AlgRange(long start, long end, ISortAlg alg) {
          this.start = start;
          this.end = end;
          this.alg = alg;
        }
    
        public ISortAlg getAlg() {
          return alg;
        }
    
        public boolean inRange(long size) {
          return size >= start && size < end;
        }
      }
    }
  • 相关阅读:
    java中用spring实现数组类型输出
    #科委外文文献发现系统——导出word模板1.0
    #科委外文文献发现系统——项目管理
    终审项目展示
    M2事后会议报告
    【Beta版本发布】爬虫队长装备全面更新!
    Beta版本测试报告
    Beta阶段爬取数目预估
    团队作业Week14——源代码管理
    Daily Scrum NO.10
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/15843721.html
Copyright © 2020-2023  润新知