首页 > 其他 > 详细

设计模式学习笔记--策略(Strategy)模式

时间:2014-04-13 03:49:32      阅读:559      评论:0      收藏:0      [点我收藏+]


写在模式学习之前


       什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式;每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案;当我们碰到模式所描述的问题,就可以直接用相应的解决方法去解决这个问题,这就是设计模式。

       设计模式就是抽象出来的东西,它不是学出来的,是用出来的;或许你根本不知道任何模式,不考虑任何模式,却写着最优秀的代码,即使以“模式专家”的角度来看,都是最佳的设计,不得不说是“最佳的模式实践”,这是因为你积累了很多的实践经验,知道“在什么场合代码应该怎么写”,这本身就是设计模式。

       有人说:“水平没到,学也白学,水平到了,无师自通”。诚然,模式背熟,依然可能写不出好代码,更别说设计出好框架;OOP理解及实践经验到达一定水平,同时也意味着总结了很多好的设计经验,但"无师自通",却也未必尽然,或者可以说,恰恰是在水平和经验的基础上,到了该系统的学习一下“模式”的时候了,学习一下专家总结的结果,印证一下自己的不足,对于提高水平还是很有帮助的。

       本系列的设计模式学习笔记,实际是对于《Java与模式》这本书的学习记录。


策略模式的定义


策略模式,其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

策略模式把行为和环境分割开来。环境类负责维持和查询行为类,各种算法则在具体策略类(ConcreteStrategy)中提供。由于算法和环境独立开来,算法的增减、修改都不会影响环境和客户端。

策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换。”


策略模式的结构


结构图


bubuko.com,布布扣


所涉及的角色


(1)环境(Context) 角色:持有一个Strategy类的引用。

(2)抽象策略(Strategy)角色:抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需的接口。

(3)具体策略(ConcreteStrategy)角色:包装了相关的算法和行为。


代码实现


class Context
{
	private Strategy strategy;
	//策略方法
	public void contextInterface()
	{
		strategy.strategyInterface();
	}
}
abstract class Strategy
{
	//策略方法
	public abstract void strategyInterface();
}
class ConcreteStrategy extends Strategy
{
	//策略方法
	public void strategyInterface()
	{
		//Write your algorithm code here
	}
}

策略模式使用场景


(1)如果一个系统里面有很多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。

(2)一个系统需要动态地在几种算法中选择一种。

(3)一个系统的算法使用的数据不可以让客户端知道。策略模式可以避免让客户端涉及到不必要接触到的复杂的和只与算法相关的数据。

(4)如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。此时,使用策略模式,把这些行为转移到相应的具体策略类里面,就可以避免使用难以维护的多重选条件选择语句,并提现面向对象设计的概念。


演示一个策略案例:排序策略系统


含4种排序算法:冒泡排序、选择排序、插入排序、快速排序。

结构图


bubuko.com,布布扣


代码实现


import java.util.*;
class Sorter
{
	private SortStrategy sortStrategy;
	public void sort()
	{
		sortStrategy.sort();
	}
	public void setStrategy(SortStrategy sortStrategy)
	{
		this.sortStrategy = sortStrategy;
	}
	public static void main(String[] args)
	{
		/*
		排序算法有很多,所以在特定情景中使用哪一种算法很重要。为了选择合适的算法,可以按照建议的顺序考虑以下标准: 
		(1)执行时间 
		(2)存储空间 
		(3)编程工作 
		对于数据量较小的情形,(1)(2)差别不大,主要考虑(3);而对于数据量大的,(1)为首要。 
		*/
		Sorter sorter = new Sorter();

		int[] a = new int[]{5,9,8,1,3,2,4,6,7};
		//SortStrategy s = new BubbleSort();
		//SortStrategy s = new SelectSort();
		//SortStrategy s = new InsertSort();
		SortStrategy s = new QuickSort();
		s.setA(a);
		s.sort();

	}
}
abstract class SortStrategy
{
	protected int[] a;
	public void setA(int[] a)
	{
		this.a = a;
	}
	public abstract void sort();
}
//冒泡排序(稳定排序):时间复杂度:O(n^2),原理是:共n-1轮排序处理,第j轮进行n-j次比较和至多n-j次交换
class BubbleSort extends SortStrategy
{	
	public void sort()
	{
		int n = a.length;
		System.out.println(Arrays.toString(a));
		for(int i=0;i<n-1;i++)	//共计n-1轮排序处理,这个i只是多少轮,与数组元素位置无关
		{
			for(int j=0;j<n-i-1;j++) //第j轮进行n-j次比较和至多n-j次交换
			{
				if(a[j]>a[j+1])//比较交换相邻元素
				{ 
					int temp;
					temp=a[j];
					a[j]=a[j+1];
					a[j+1]=temp;
				}
			}
			System.out.println(Arrays.toString(a));
		}		
	}
}
//选择排序(不稳定排序):时间复杂度:O(n^2),原理是:共n-1轮排序处理,每轮找出最小的放在相应位置
class SelectSort extends SortStrategy
{
	public void sort()
	{
		int n = a.length;
		System.out.println(Arrays.toString(a));
		for(int i=0;i<n-1;i++)	//共计n-1轮排序处理,这个i只是多少轮,与数组元素位置无关
		{
			int k = i;
			for(int j=i+1;j<n;j++) //每次扫描选择最小项
			{
				if(a[j] < a[k])
				{
					k = j;
				}
			}
			if(k != i)//最小项移到列的正确位置
			{ 
				int temp;
				temp=a[i];
				a[i]=a[k];
				a[k]=temp;
			}
			System.out.println(Arrays.toString(a));
		}		
	}
}
//插入排序(稳定排序):时间复杂度:O(n^2),原理是:对数组中的第i个元素,认为它前面的i-1个已经排序好,然后将它插入到前面的i-1个元素中。
//插入排序对少量元素的排序较为有限
class InsertSort extends SortStrategy
{
	public void sort()
	{
		int n = a.length;
		System.out.println(Arrays.toString(a));
		for(int i=1;i<n;i++)	////循环从第二个数组元素开始,因为第一个作为最初已排序部分
		{
			int temp=a[i];//temp标记为未排序第一个元素 
			int j=i-1; 
			while (j>=0 && a[j]>temp)/*将temp与已排序元素从小到大比较,寻找temp应插入的位置*/ 
			{ 
				a[j+1]=a[j]; 
				j--; 
			} 
			a[j+1]=temp; 
			System.out.println(Arrays.toString(a));
		}		
	}
}
//快速排序(不稳定排序):时间复杂度,O(nlogn),最坏情况为O(n^2),是对冒泡排序的改进,最快的已知排序,适用于排序大列表
//基本思想:通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的小,然后对这两部分继续快速排序,达到整个数据变成有序序列。
class QuickSort extends SortStrategy
{
	public void sort()
	{
		sort(0,a.length-1);	
	}
	private int partition(int a[],int low,int high)
    {
        int key = a[low];
         
        while(low<high)
        {
            while(low<high && a[high]>=key)
                high--;
            a[low] = a[high];
             
            while(low<high && a[low]<=key)
                low++;
            a[high] = a[low];
        }
        a[low] = key;
        return low;
    }     
    private void sort(int low,int high)
    {
        if(low<high)
        {
            int result = partition(a,low,high);
            sort(low,result-1);
            sort(result+1,high);
        }
		System.out.println(Arrays.toString(a));
    }
}

设计模式学习笔记--策略(Strategy)模式,布布扣,bubuko.com

设计模式学习笔记--策略(Strategy)模式

原文:http://blog.csdn.net/puma_dong/article/details/23503651

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!