您的位置:首页 > 编程语言 > Java开发

java设计模式--策略模式

2014-04-11 11:49 239 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: