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 
原文地址:https://www.cnblogs.com/baiduligang/p/4247426.html