首先我们需要知道策略模式与状态模式是如此的相似,就犹如一对双胞胎一样。只不过状态模式是通过改变对象内部的状态来帮助对象控制自己的行为,而策略模式则是围绕可以互换的算法来创建成功业务的两者都可用于解决同一个问题:带有大量的if..else…等条件判断语句来进行选择的(小弟初学,不知这样理解是否有误??有误望指出…)。

在我们的生活中我们可以通过很多种不同的方式来完成一件事情,这里的每一种方式都可以称作为一种策略。我们可以根据环境、条件等因素的不同选择不同的策略来完成这件事情。比如说出去旅游,我们可以选择坐火车、坐飞机、坐大巴、骑自行车,甚至徒步等等方式。如果想舒适快速我们可以选择飞机,节约钱我们可以选择火车和大巴,离家近的我们可以骑自行车,每一种方式都可以到达目的地。但是总有一种方式是当前最适合你的。你会选择哪种出行方式呢?

在软件开发过程中是一样的,我们可能有很多种方法可以实现某一个功能,但是我们需要一种简单、高效的途径可以使得系统能够灵活的解决问题。这就是策略模式的设计动机。

一、模式定义

在前面中对策略模式应该有了一个最初步的认识。那么什么是策略模式呢?所谓策略模式就是定义了算法族,分别封装起来,让他们之前可以互相转换,此模式然该算法的变化独立于使用算法的客户。

在软件系统中有很多种方法可以实现同一个功能,比如排序算法它有冒泡排序、选择排序、快速排序、插入排序等等。这里我们有一种硬编码方法,就是讲所以的排序算法全部写在一个类中,每一种算法的具体实现对应着一个方法,然后写一个总方法通过if…else…来判断选择具体的排序算法,但是这样做存在几个问题。

第一:如果需要增加新的算法,则需要修改源代码。

第二:如果更新了排序算法,那么需要在客户端也需要修改代码,麻烦。

第三:充斥着大量的if…else…语句,代码维护比较困难。

所以为了解决这些问题,我们可以定义一些独立的类来封装不同的算法,每一个独立的类对应着一个具体的算法实现,在这里我们就将这里每一个独立的类称之为一个策略。

二、模式结构

下图为策略模式的结构:

这个UML图与状态模式的几乎一模一样,状态模式是通过改变对象内部的状态来帮助对象控制自己的行为,我们可以这样理解状态模式其实是对状态进行封装,它是将动作动作的实现和责任进行分割,把动作委托到代表当前状态的对象。而策略模式是对算法进行封装,把算法的责任和算法本身进行分割开来,同时委派给不同的对象进行管理。策略模式是将一个系列的算法封装到一系列的策略里面。

其实对于算法的选择,策略模式并不关心,它只是对算法进行封装,至于算法什么时候什么地方使用什么算法都是客户所决定的,这样就提高了系统的灵活性,但同时也增加了客户的负担,因为客户需要清楚知道选择什么样的算法对自己最有利,这就需要客户对每一个算法都清楚知道他们的区别。

三、模式实现

我们都知道排序算法有很多种,但是什么时候选择冒泡排序,什么时候选择选择排序,什么时候选择插入排序,所以这里用排序算法来演示策略模式的实现。 
      首先我们先来看看在没有使用策略模式的情况。

public void selectSort(String type){
if("type1".equals(type)){
//选择快速排序
}
else if("type2".equals(type)){
//选择插入排序
}
else if("type3".equals(type)){
//选择冒泡排序
}
else if("type4".equals(type)){
//选择选择排序
}
......
}

  对于这样的代码实现,除了代码中充斥着大量的if…else if…else,导致程序可维护性很差,而且系统的可扩展性不好,如果某个排序模块进行更改了,有可能需要修改源代码。所以在对于这样的情景是非常合适使用策略模式的。

那么如何使用策略模式呢?首先我们需要定义一个接口,该接口提供排序算法,然后定义想要的排序算法,实现给接口即可。如下:

首先是Sort接口,该接口定义了排序算法,所有的排序算法都应该实现该接口。

public interface Sort{
public abstract int[] sort(int arr[]);
}

然后是三个具体的排序算法,他们实现Sort接口。

冒泡排序:BubbleSort.java

public class BubbleSort implements Sort{
public int[] sort(int arr[]){
int len=arr.length;
for(int i=0;i<len;i++){
for(int j=i+1;j<len;j++){
int temp;
if(arr[i]>arr[j]){
temp=arr[j];
arr[j]=arr[i];
arr[i]=temp;
}
}
}
System.out.println("冒泡排序");
return arr;
}
}

插入排序:InsertionSort.java

public class InsertionSort implements Sort {
public int[] sort(int arr[]) {
int len = arr.length;
for (int i = 1; i < len; i++) {
int j;
int temp = arr[i];
for (j = i; j > 0; j--) {
if (arr[j - 1] > temp) {
arr[j] = arr[j - 1]; } else
break;
}
arr[j] = temp;
}
System.out.println("插入排序");
return arr;
}
}

选择排序:SelectSort.java

public class SelectionSort implements Sort {
public int[] sort(int arr[]) {
int len = arr.length;
int temp;
for (int i = 0; i < len; i++) {
temp = arr[i];
int j;
int samllestLocation = i;
for (j = i + 1; j < len; j++) {
if (arr[j] < temp) {
temp = arr[j];
samllestLocation = j;
}
}
arr[samllestLocation] = arr[i];
arr[i] = temp;
}
System.out.println("ѡ������");
return arr;
}
}

最后就是测试类客户端了Client.java

public class ArrayHandler
{
private Sort sortObj; public int[] sort(int arr[])
{
sortObj.sort(arr);
return arr;
} public void setSortObj(Sort sortObj) {
this.sortObj = sortObj;
}
}
public class Client
{
public static void main(String args[])
{
int arr[]={1,4,6,2,5,3,7,10,9};
int result[];
ArrayHandler ah=new ArrayHandler(); Sort sort = new SelectionSort(); //使用选择排序 ah.setSortObj(sort); //设置具体策略
result=ah.sort(arr); for(int i=0;i<result.length;i++)
{
System.out.print(result[i] + ",");
}
}
}

运行结果

選擇排序 
      1,2,3,4,5,6,7,9,10,

四、模式优缺点

优点

      1、策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。 
      2、策略模式提供了可以替换继承关系的办法。 
      3、使用策略模式可以避免使用多重条件转移语句

缺点

      1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。 
      2、策略模式将造成产生很多策略类,

五、使用场景

1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 
      2、一个系统需要动态地在几种算法中选择一种。 
     3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

设计模式:策略模式(Stratege)的更多相关文章

  1. 15. 星际争霸之php设计模式--策略模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  2. [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)

    [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...

  3. linkin大话设计模式--策略模式

    linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi]  策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...

  4. [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  5. 设计模式-策略模式(Strategy Model)

    1.概述     在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能.     如在人物比较排序的实现中,我们有 ...

  6. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  7. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  8. javascript 设计模式-----策略模式

    在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...

  9. JAVA 设计模式 策略模式

    用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构

随机推荐

  1. 51 Nod 1272 简单思维题

    1272 最大距离  题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给出一个长度为N的整数数组A,对于每一个数组元素 ...

  2. 灰度图像--图像分割 阈值处理之P-Tile阈值

    学习DIP第53天 转载请标明本文出处:***http://blog.csdn.net/tonyshengtan ***,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:http ...

  3. 简单快捷的方式从vps下载文件

    安装setuptools 1) 最简单安装,假定在ubuntu下 sudo apt-get install python-setuptools SimpleHTTPServer 是单线程的临时服务,建 ...

  4. HDU6140--Hybrid Crystals(思维)

    Hybrid Crystals Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  5. Chrome 神器,神奇的技巧

    谷歌开发者工具是前端日常不可缺少的神奇,写布局,找 bug,优化加载速度统统靠他.但是你真的了解他么?这篇文章是专门介绍谷歌浏览器各种好用小技巧的.不是什么长篇大论,旨在提高你的开发效率,早日完工回家 ...

  6. [CSP-S模拟测试]:那一天我们许下约定(DP+组合数学)

    题目传送门(内部题2) 输入格式 每个测试点有多组测试数据.对于每组数据,有一行共三个整数$N$,$D$,$M$含义如题.输入结束标识为$“0 0 0”$ (不含引号). 输出格式 对于每组数据,输出 ...

  7. C++入门经典-例8.10-实现抽象类中的成员函数

    1:抽象类通常作为其他类的父类,如果从抽象类派生的子类是抽象类,则子类必须实现父类中的所有纯虚函数.代码如下: // 8.10.cpp : 定义控制台应用程序的入口点. // #include &qu ...

  8. [学习笔记] Uplift Decision Tree With KL Divergence

    Uplift Decision Tree With KL Divergence Intro Uplift model 我没找到一个合适的翻译,这方法主要应用是,探究用户在给予一定激励之后的表现,也就是 ...

  9. leetcode-hard-array-128. Longest Consecutive Sequence

    mycode   92.62% class Solution(object): def longestConsecutive(self, nums): """ :type ...

  10. rocketmq 以广播方式实现消费者消费消息

    package com.bfxy.rocketmq.model; import java.util.List; import org.apache.rocketmq.client.consumer.D ...