zoukankan      html  css  js  c++  java
  • 策略模式

    定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。我们知道,工厂模式是解耦对象的创建和使用,观察者模式是解耦观察者和被观察者。策略模式跟两者类似,也能起到解耦的作用,不过,它解耦的是策略的定义、创建、使用这三部分。

    策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。因为所有的策略类都实现相同的接口,所以,客户端代码基于接口而非实现编程,可以灵活地替换不同的策略

    public interface ISortAlg {
        void sort(String filePath);
    }

    定义策略实现类

    package com.lf.pattern.strategy;
    
    public class ConcurrentExternalSort implements ISortAlg{
    
        @Override
        public void sort(String filePath) {
    
        }
    }
    package com.lf.pattern.strategy;
    
    public class ExternalSort implements ISortAlg{
        
        @Override
        public void sort(String filePath) {
    
        }
    }
    package com.lf.pattern.strategy;
    
    public class QuickSort implements ISortAlg{
    
        @Override
        public void sort(String filePath) {
    
        }
    }
    package com.lf.pattern.strategy;
    
    public class MapReduceSort implements ISortAlg{
    
        @Override
        public void sort(String filePath) {
    
        }
    }

    定义策略工厂类,从工厂里取对象

    package com.lf.pattern.strategy;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 策略工厂类
     */
    public class SortAlgFactory {
    
        private static final Map<String, ISortAlg> algs = new HashMap<>();
    
        static {
            algs.put("QuickSort", new QuickSort());
            algs.put("ExternalSort", new ExternalSort());
            algs.put("ConcurrentExternalSort", new ConcurrentExternalSort());
            algs.put("MapReduceSort", new MapReduceSort());
        }
    
        public static ISortAlg getSortAlg(String type) {
            if (type == null || type.isEmpty()) {
                throw new IllegalArgumentException("type should not be empty.");
            }
            return algs.get(type);
        }
    }

    策略的使用:

    package com.lf.pattern.strategy;
    
    import java.io.File;
    
    public class IfSorter {
    
            private static final long GB = 1000 * 1000 * 1000;
    
            public void sortFile(String filePath) {
                // 省略校验逻辑
                File file = new File(filePath);
                long fileSize = file.length();
                ISortAlg sortAlg;
                //消除大量的if/else,让代码结构更优雅
                if (fileSize < 6 * GB) { // [0, 6GB)
                    sortAlg = SortAlgFactory.getSortAlg("QuickSort");
                } else if (fileSize < 10 * GB) { // [6GB, 10GB)
                    sortAlg = SortAlgFactory.getSortAlg("ExternalSort");
                } else if (fileSize < 100 * GB) { // [10GB, 100GB)
                    sortAlg = SortAlgFactory.getSortAlg("ConcurrentExternalSort");
                } else { // [100GB, ~)
                    sortAlg = SortAlgFactory.getSortAlg("MapReduceSort");
                }
                sortAlg.sort(filePath);
            }
    }

    消除大量if/else,代码优雅化、健壮化

    package com.lf.pattern.strategy;
    
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    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;
            }
        }
    }

    如果不想改动代码,则可以做成注解或者配置,扫描注解或配置加载进list,然后查表法即可

  • 相关阅读:
    素数筛代码
    stringsream用法
    MySQL学习(四)——外键
    MySQL学习(三)——Java连接MySQL数据库
    MySQL学习(二)——SQL语句创建删除修改以及中文乱码问题
    MySQL学习(一)——启动和登录MySql遇到的问题及解决
    BootStrap学习(三)——重写首页之导航栏和轮播图
    BootStrap学习(二)——重写首页之topbar
    BootStrap学习(一)——BootStrap入门
    jQuery学习(八)——使用JQ插件validation进行表单校验
  • 原文地址:https://www.cnblogs.com/flgb/p/14813087.html
Copyright © 2011-2022 走看看