策略模式(Strategy):它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户。

  策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。事实上你可以将一个继承自抽象策略类的称为具体策略,就是策略模式中的策略1,策略2......

  策略模式的优点:

  策略模式的Strategy类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取出这些算法的公共功能。策略模式的另一个优点是简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

  说了这么多,策略模式究竟解决的是什么问题呢?

  策略模式就是用来封装算法的,但在实践中,我们发现可以用它来封装几乎任何类型的规则,只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式处理这种变化的可能性。

  在基本策略模式中,选择所用具体实现的职责由客户端对象承担,并转给策略模式的Context对象。

  策略模式的结构图:

      

  策略模式的具体实现代码示例:

namespace 策略模式
{
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("我钓了一条鱼,应该怎么煮呢?"); Context context;
context = new Context(new ConcreteStrategyA());  //客户端依赖具体实现类了
context.RunMethod(); context = new Context(new ConcreteStrategyB());
context.RunMethod(); Console.ReadKey();
}
} //抽象算法类
public abstract class Strategy
{
//算法方法
public abstract void AlgorithmInterface();
} //具体策略1
public class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("加水、上蒸笼、开火、清蒸!");
}
} //具体策略2
public class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("热锅、放油、红烧!");
}
} //上下文
public class Context
{
Strategy strategy; //构造方法接收具体对象
public Context(Strategy strategy)
{
this.strategy = strategy;
} //调用方法
public void RunMethod()
{
strategy.AlgorithmInterface();
}
}
}

  以上代码感觉到了什么?策略模式不管创建,它做的事非常少,少到什么程度?

  你传个对象给我,我帮你调用这个对象的方法(这个工作主要通过Context来维护),我不管你这对象怎么创建,但你得给我个对象。策略模式不管对象的创建,那么它实质上是什么。用类图说明。

  

  从上面的类图看到一个问题。因为,我调用你时,我要给你传个对象,上面的例子直接new()。因此,客户端依赖于具体实现类了。

  所以,策略模式通常与一些创建对象的模式混合使用,比如负责维护调用具体策略的Context类搭配个简单工厂:

    public class Context
{
Strategy strategy = null;
//调用方法
public void RunMethod(string type)
{ switch (type)
{
default:
case "清蒸":
strategy = new ConcreteStrategyA();
break;
case "红烧":
strategy = new ConcreteStrategyB();
break;
}
strategy.AlgorithmInterface();
}
}

  这样外部就依赖Context类了:

        static void Main(string[] args)
{
Console.WriteLine("我钓了一条鱼,应该怎么煮呢?"); Context context = new Context();
context.RunMethod("清蒸");
context.RunMethod("红烧"); Console.ReadKey();
}

  最后回顾一下:

  策略模式不管对象创建,它的目的在于封装不同的算法,根据传入的对象,调用具体的策略方法,在上面的示例程序加入简单工厂模式的原因,是因为要创建对应的具体类,要分清哪些代码属于哪个模式的范畴。

  搞了半天,策略模式就是一个类封装一个算法,实现一个算法接口,然后搞个Context来调用这些算法。

 
 
分类: 设计模式
 
0
0
 
(请您对文章做出评价)
 

策略模式 - OK的更多相关文章

  1. javascript设计模式:策略模式

    前言 策略模式有效利用组合.委托.多态等技术和思想,可以有效避免多重条件选择语句. 策略模式对开放-封闭原则提供了很好的支持,将算法封装在strategy中,使得他们易于切换.理解.扩展. 策略模式中 ...

  2. StrategyPattern (策略模式)

    /** * 策略模式 * @author TMAC-J * 根据环境的不同选择不同的策略,把策略用接口抽象出来 */ public class StrategyPattern { interface ...

  3. JAVA 设计模式之策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...

  4. Java设计模式之策略模式(Strategy)

    前言: 最近一直在学习基于okHttp网络请求,学习的过程中就想起了之前项目中有这么一个需求不同的接口要采用不同的加密方式,比如登录之前要采用RSA加密,登录之后要采用AES加密,当时是采用靠传递一个 ...

  5. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...

  6. 《Head First 设计模式》之策略模式

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5915202.html 模式名称 策略模式(Strategy Pattern) 需求 模拟鸭子游戏,游戏 ...

  7. 学C#之设计模式系列笔记(1)策略模式

    一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...

  8. PHP 策略模式

    策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化.策略模式把对象本身和运算规则区分开来,其功能非常强大,因为这个设计模式本身的核心思想 ...

  9. php实现设计模式之 策略模式

    策略模式:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化.是一种行为模式. 策略模式包含三种角色 1 抽象策略角色: 策略类,通常由一个接口或 ...

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

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

随机推荐

  1. Android 侧滑(双向滑动菜单)效果

    下面看看我们如何使用它,达到我们想要的效果 public class MainActivity extends Activity { /** * 双向滑动菜单布局 */ private SliderM ...

  2. [LeetCode] 147. Insertion Sort List 解题思路

    Sort a linked list using insertion sort. 问题:实现单向链表的插入排序. 这是比较常规的一个算法题目. 从左往右扫列表,每次将指针的下一个元素插入前面已排好序的 ...

  3. 求一个数组中第K小的数

    面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...

  4. sicily 1035. DNA matching

    题意:判断基因链是否匹配,匹配的双链数加1,并要标记,下次比较不能重用! 解法: 打擂台法 #include<iostream> #include<string> #inclu ...

  5. 回调函数的意义以及python实现

    因工作需要,最近在学习使用python来解析各种文件,包括xmind,xml,excel,csv等等. 在学习python解析XML的时候看到这样一段话: 3.ElementTree(元素树) Ele ...

  6. iOS--九宫格布局

    [self rankWithTotalColumns: andWithAppW: andWithAppH:]; //九宫格布局 - (void)rankWithTotalColumns:(int)to ...

  7. iOS UIView指定显示摸一个角弧形显示

    关键代码: UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect: view.bounds byRoundingCorner ...

  8. CSU1659: Graph Center(最短路)

    Description The center of a graph is the set of all vertices of minimum eccentricity, that is, the s ...

  9. 动态从数据库读取菜单(ASP.NET版)

    这几天一直打算做个从数据读取导航菜单的效果,以前做的时候都是写死的(太死了),好了话不多说,先看效果! 我是个小菜,高手请不要喷!我在网上查了好久,说用menu控件,但是我用了不太好!最后我决定用re ...

  10. 3:url无规律的多页面爬取

    试例网站:豆瓣电影TOP250:http://movie.douban.com/top250 关键点:在审查元素下查看后页即可以看到跳转的url.而且最后一页就此属性就没有了. 由于关键是实现分页,所 ...