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

    策略模式(Strategy)

    策略模式(Strategy Pattern)中体现了两个非常基本的面向对象设计的原则:
    a.封装变化的概念
    b.编程中使用接口,而不是对接口的实现

    策略模式的定义:
    a.定义一组算法,将每个算法都封装起来,并且使它们直接可以互换。
    b.策略模式使这些算法在客户端调用它们的时候能够互不影响地变化。


    策略模式的意义:
    a.策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是弱连接的关系
    b.弱连接的特性使软件具有更强的可扩展性,易于维护,更重要的是,它大大提高了软件的可重用性.

    策略模式的组成:
    -抽象策略角色:策略类,通常由一个接口或者抽象类实现
    -具体策略角色:包装了相关的算法和行为
    -环境角色:持有一个策略类的引用,最终给客户端调用的

    策略模式的实现:
    -策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而
    使得它们可以相互替换。
    -策略模式使得算法可以在不影响到客户端的情况下发生变化。使用策略模式可以把行为和环境分割开来。
    -环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开发,算法的修改都不会
    影响环境和客户端


    策略模式的编写步骤:
    1.对策略对象定义一个公共接口
    2.编写策略类,该类实现了上面的公共接口
    3.在使用策略对象的环境类中保存一个对策略对象的引用
    4.在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值。


    策略模式的缺点:
    1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类
    2.造成很多的策略类


    针对策略模式的缺点,看看方案:
    采用工厂模式

     

    举例1:

    实现两个数字的加,减,乘,除功能

    复制代码
    先定义一个公共接口:
    public interface Strategy
    {
        public int calculate(int a,int b);
    }
    
    编写策略类:
    加法策略类:
    public class AddStrategy implements Strategy
    {
        @Override
        public int calculate(int a, int b)
        {
            return a + b;
        }
    }
    
    减法策略类:
    public class SubtractStratagy implements Strategy
    {
        @Override
        public int calculate(int a, int b)
        {
            return a - b;
        }
    }
    
    乘法策略类:
    public class MultiplyStrategy implements Strategy
    {
        @Override
        public int calculate(int a, int b)
        {
            return a * b;
        }
    }
    
    除法策略类:
    public class DivideStrategy implements Strategy
    {
        @Override
        public int calculate(int a, int b)
        {
            return a / b;
        }
    }
    
    
    
    创建一个环境类:
    public class Environment
    {
        private Strategy strategy;
        
        public Environment(Strategy strategy)
        {
            this.strategy = strategy;
        }
    
        public void setStrategy(Strategy strategy)
        {
            this.strategy = strategy;
        }
        
        public int calculate(int a,int b)
        {
            return strategy.calculate(a, b);
        }
    }
    
    创建一个测试类:
    public class Client
    {
        public static void main(String[] args)
        {
            AddStrategy add = new AddStrategy();
            SubtractStratagy sub = new SubtractStratagy();
            MultiplyStrategy mul = new MultiplyStrategy();
            DivideStrategy div = new DivideStrategy();
            
            Environment environment = new Environment(add);
            System.out.println(environment.calculate(2, 5));
            
            environment.setStrategy(sub);
            System.out.println(environment.calculate(2, 5));
            
            environment.setStrategy(mul);
            System.out.println(environment.calculate(2, 5));
            
            environment.setStrategy(div);
            System.out.println(environment.calculate(2, 5));
        }
    }
    
    到此第一个策略模式的案例就完成了
    复制代码

     

    举例2:

    对数组类的数字进行排序,有冒泡排序,快速排序,折半排序

    复制代码
    编写接口:
    public interface SortStrategy
    {
        public int[] sort(int[] nums);
    }
    
    编写策略类:冒泡排序,快速排序,折半排序
    冒泡排序策略类:
    public class BubbleSortStrategy implements SortStrategy
    {
        /**
         * 功能:冒泡排序
         */
        @Override
        public int[] sort(int[] nums)
        {
            for(int i = 0;i < nums.length-1;i++)
            {
                for(int j = 0;j < nums.length-i-1;j++)
                {
                    if(nums[j] > nums[j+1])
                    {
                        int temp = nums[j];
                        nums[j] = nums[j+1];
                        nums[j+1] = temp;
                    }
                }
            }
            return nums;
        }
    }
    
    
    快速排序策略类:
    public class QuicklySortStrategy implements SortStrategy
    {
        @Override
        public int[] sort(int[] nums)
        {
            return quicklySort(nums,0,nums.length-1);
        }
        
        private int[] quicklySort(int[] nums,int low,int high)
        {
            if(low < high)
            {
                int povitePosition = adjust(nums,low,high);
                quicklySort( nums , low , povitePosition - 1); 
                quicklySort( nums , povitePosition + 1 , high ); 
            }
            
            return nums;
        }
        
        private int adjust(int[] nums,int low,int high)
        {
            int pivote = nums[low]; 
            while(low < high)
            {
                while(high > low && compare(pivote,nums[high])<=0)
                {
                    high--;
                }
                nums[low] = nums[high];
                
                while(low < high && compare( pivote , nums[low] ) >= 0)
                {
                    low++;
                }
                nums[high] = nums[low];
            }
            nums[low] = pivote;
            return low;
        }
        
        private int compare(int num1,int num2)
        {
            return num1 - num2;
        }
    }
    
    
    折半排序策略类:
    public class BinaryInsertSortStrategy implements SortStrategy
    {
        @Override
        public int[] sort(int[] nums)
        {
            return binaryInsertSort(nums);
        }
    
        private int[] binaryInsertSort(int[] data)
        {
            for (int i = 1; i < data.length; i++)
            {
                if (data[i] < data[i - 1])
                {
                    // 缓存i处的元素值
                    int tmp = data[i];
                    // 记录搜索范围的左边界
                    int low = 0;
                    // 记录搜索范围的右边界
                    int high = i - 1;
                    while (low <= high)
                    {
                        // 记录中间位置
                        int mid = (low + high) / 2;
                        // 比较中间位置数据和i处数据大小,以缩小搜索范围
                        if (data[mid] < tmp)
                        {
                            low = mid + 1;
                        } else
                        {
                            high = mid - 1;
                        }
                    }
                    // 将low~i处数据整体向后移动1位
                    for (int j = i; j > low; j--)
                    {
                        data[j] = data[j - 1];
                    }
                    data[low] = tmp;
                }
            }
            return data;
        }
    }
    
    
    环境类:
    public class Environment
    {
        private SortStrategy sortStrategy;
        
        public Environment(SortStrategy sortStrategy)
        {
            this.sortStrategy = sortStrategy;
        }
        
        public int[] sort(int[] nums)
        {
            return sortStrategy.sort(nums);
        }
    
        public void setSortStrategy(SortStrategy sortStrategy)
        {
            this.sortStrategy = sortStrategy;
        }
    }
    
    
    测试类:
    public class SortClient
    {
        public static void main(String[] args)
        {
            int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
            
            BubbleSortStrategy bubble = new BubbleSortStrategy();
            QuicklySortStrategy quick = new QuicklySortStrategy();
            BinaryInsertSortStrategy binary = new BinaryInsertSortStrategy();
            
            Environment env = new Environment(bubble); 
            data = env.sort(data);
            
            System.out.println("冒泡排序:");
            for(int i = 0;i < data.length;i++)
            {
                System.out.print(data[i]+" ");
            }
            
            System.out.println("");
            env.setSortStrategy(quick);
            data = env.sort(data);
            System.out.println("快速排序:");
            for(int i = 0;i < data.length;i++)
            {
                System.out.print(data[i]+" ");
            }
            
            
            System.out.println("");
            env.setSortStrategy(binary);
            data = env.sort(data);
            System.out.println("折半排序:");
            for(int i = 0;i < data.length;i++)
            {
                System.out.print(data[i]+" ");
            }
        }
    }
    
    输出结果:
    
    冒泡排序:
    1 2 3 4 5 6 7 8 9 
    快速排序:
    1 2 3 4 5 6 7 8 9 
    折半排序:
    1 2 3 4 5 6 7 8 9 
  • 相关阅读:
    SP338 ROADS
    [Usaco2008 Mar]牛跑步
    [Cerc2005]Knights of the Round Table
    [Poi2005]Piggy Banks小猪存钱罐
    Pku1236 Network of Schools
    PKU2186 Popular Cows 受欢迎的牛
    黑暗城堡
    入门OJ:最短路径树入门
    Sqli-labs
    Sqli-labs
  • 原文地址:https://www.cnblogs.com/baiduligang/p/4247425.html
Copyright © 2011-2022 走看看