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

1,策略模式定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

策略模式的组成:

—抽象策略角色: 策略类,通常由一个接口或者抽象类实现。 
—具体策略角色:包装了相关的算法和行为。 
—环境角色:持有一个策略类的引用,最终给客户端调用。 

2,策略模式适场景

(1)多个相关的类中,仅行为不同,即一个系统中需要在几个不同的算法中选择时。比如中出行中,我们选择交通方式火车、飞机、自行车、汽车等。

(2)一个算法的不同变体时。比如一个收取暖费的算法,不同的收费方式如按房屋面积、按供热焦耳量、按面积和热量混合法等 。

(3)不想暴露算法给使用者。比如,有一个复杂算法或算法中有相对应的数据结构不想让使用者知道。

(4)一个行为中有多个条件时。比如,有多个条件语句,而且实现比较复杂或比较长时,使用策略模式,除了结构清晰外,维护某一分支也比较方便。

3,策略模式优点

(1)抽象策略类和具体策略角色为环境类定义了一系列可以重用的算法或行为,并且继承有助于取出共用部分的算法。

(2)提供了可以替换继承关系的办法。可以创建一个环境类的子类,里面封装不同的行为,通过环境类来驱动策略。但这样也会导致环境类中的行为包含了具体实现,使用程序难以理解,难以维护。

(3)消除了复杂的IF..ELSE。含有许多复杂条件语句的代码可以使用策略模式来使逻辑更加清晰,易于维护。

(4)实了具有相同类型的多个行业的切换。让用户在多个策略中切换行为。

4,策略模式缺点

(1)需要事先知道所有策略类行为有何不同,才能让用户很好的选择。容易向使用者暴露策略中的各个行为。

(2)环境类和策略类之间产生通信开销。

(3)需要创建很多策略类。后面会说到享元模式,一定程度上减少类。

5,策略模式应用

(1)华山论剑

还是以熟悉的华山论剑为例,比赛方式(也就是三个具体策略类)有“比外功、比内功、比招式”,场景为“华山”(也就是场景类HuaShan),开始比赛了,主持人事先知道这几种比赛方式(也就是具体策略类),主持人(也就是具体使用者)让依次以这几种方式进行。

先看一下UML类图(在VS中使用类图,可以参考我前面的文章:在Visual Studio 2013/2015中设计UML类图

下面是具体代码:

抽象策略类 LunJian

public abstract class LunJian
{
public abstract void BiSai();
}

具体策略类 WaiGong NeiGong ZhaoShi

public class WaiGong : LunJian
{
public override void BiSai()
{
Console.WriteLine("外功比试开始了!");
}
}
public class NeiGong : LunJian
{
public override void BiSai()
{
Console.WriteLine("内功比试开始了!");
}
}
public class ZhaoShi : LunJian
{
public override void BiSai()
{
Console.WriteLine("招式比试开始了!");
}
}

场景类(也就是策略上下文 ) HuaShan

public class HuaShan
{
LunJian lunJian=null; public void SetLunJian(LunJian lunJian)
{
this.lunJian = lunJian;
} public void BiShi()
{
this.lunJian.BiSai();
}
}

使用者,就是控制台应用程序

class Program
{
static void Main(string[] args)
{
HuaShan huanShan = new HuaShan(); huanShan.SetLunJian(new WaiGong());
huanShan.BiShi(); huanShan.SetLunJian(new NeiGong());
huanShan.BiShi(); huanShan.SetLunJian(new ZhaoShi());
huanShan.BiShi(); Console.ReadLine();
}
}

依次给出三种比试方式策略,运行结果如下:

(2)华山论剑升级版

上面的示例比较简单,假如我们比试开始的时候,还需要点名两个比赛选手,这就需要在具体策略类的方法中增加参数。我们增加BiShi()方法参数,改进后代码如下:

抽象策略类 LunJian

public abstract class LunJian
{
public abstract void BiSai(string player1,string player2); }

具体策略类 WaiGong NeiGong ZhaoShi

public class WaiGong : LunJian
{
public override void BiSai(string player1,string player2)
{
Console.WriteLine("外功比试开始了!"+string.Format(" {0} 和 {1} 出场",player1,player2));
}
}
public class NeiGong : LunJian
{
public override void BiSai(string player1, string player2)
{
Console.WriteLine("内功比试开始了!" + string.Format(" {0} 和 {1} 出场", player1, player2));
}
}
public class ZhaoShi : LunJian
{
public override void BiSai(string player1, string player2)
{
Console.WriteLine("招式比试开始了!" + string.Format(" {0} 和 {1} 出场", player1, player2));
}
}

场景类(也就是策略上下文 ) HuaShan

public class HuaShan
{
LunJian lunJian=null; public void SetLunJian(LunJian lunJian)
{
this.lunJian = lunJian;
} public void BiShi(string player1,string player2)
{
this.lunJian.BiSai(player1,player2);
}
}

使用者,就是控制台应用程序

    class Program
{
static void Main(string[] args)
{
HuaShan huanShan = new HuaShan(); huanShan.SetLunJian(new WaiGong());
huanShan.BiShi("黄药师","欧阳锋"); huanShan.SetLunJian(new NeiGong());
huanShan.BiShi("洪七公","一灯大师"); huanShan.SetLunJian(new ZhaoShi());
huanShan.BiShi("欧阳锋","洪七公"); Console.ReadLine();
}
}

运行结果:

华山论剑的业务肯定比这个要复杂,上面的出场人不同,比赛方式不同,甚至还其他不同的规则出现。

如果我们不使用策略模式,而通过传统的if...else来写,不但要写很长的代码,还需要条件语句多次嵌套。

最主要的是代码的可读性较差,而且难以再解。

6,总结

(1)策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
(2)在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。
(3)策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

7.实例源代码

https://github.com/yubinfeng/BlogExamples.git

==============================================================================================

返回目录

<如果对你有帮助,记得点一下推荐哦,如有有不明白或错误之处,请多交流>

<对本系列文章阅读有困难的朋友,请先看 《.net 面向对象编程基础》和 《.net 面向对象程序设计进阶》 >

<转载声明:技术需要共享精神,欢迎转载本博客中的文章,但请注明版权及URL>

.NET 技术交流群:467189533

==============================================================================================

[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)的更多相关文章

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

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

  2. 24种设计模式-策略模式(Strategy Pattern)

    一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...

  3. 24种设计模式--策略模式【Strategy Pattern】

    刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜赔了夫人有折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景 ...

  4. [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)

    [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...

  5. PHP设计模式-策略模式 转

    策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个 ...

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

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

  7. 设计模式:Strategy 策略模式 -- 行为型

    设计模式 策略模式Strategy(对象行为型) 这是几年前写的文字(转载做的笔记更准确些),发觉还是废话多了点. 其实,核心就是5.结构中的UML图 5.1 和 5.2(新增).现在看这张图就觉得一 ...

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

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

  9. 面向对象设计模式--策略模式Strategy

    策略模式的UML类图(VS2013 C++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...

随机推荐

  1. JVM内存划分基础知识

    第一部分 JVM内存划分 目录 Java垃圾回收概况 Java内存区域 Java对象的访问方式 Java内存分配机制 Java GC机制 垃圾收集器 Java垃圾回收概况 Java GC(Garbag ...

  2. jQuery 对象与Dom 对象互转

    jQuery 对象与Dom 对象互转: $obj --[i],get(i)-->obj --$(obj)-->$obj; obj--$($(obj))-->$obj,多包装了也是$o ...

  3. 用Zephir编写PHP扩展

    自从NodeJS,和Golang出来后,很多人都投奔过去了.不为什么,冲着那牛X的性能.那PHP的性能什么时候能提升一下呢?要不然就会被人鄙视了.其实大牛们也深刻体会到了这些威胁,于是都在秘密开发各种 ...

  4. Session是否为新建情况的判断

    Session是否为新建情况的判断: Xml: <?xml version="1.0" encoding="UTF-8"?> <web-app ...

  5. WinMerge文件编码设置

    http://blog.sina.com.cn/s/blog_7575fab10101o0na.html 系统默认是System codepage,我们要选用Custom codepage.值得注意的 ...

  6. HDU5875

    Function Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

  7. 设计社区Dribbble VS. Bēhance,你选谁?

    Behance和Dribbble都是主流的设计作品分享平台,为广大设计师同胞们带来了莫大的便利,所以很多设计师通常两个社区都会关注.很多设计师在展示个人信息的时候,通常也会把这两个平台的链接放到个人资 ...

  8. Plugin execution not covered by lifecycle configuration的解决方案

    pom配置文件中,提示错误:Plugin execution not covered by lifecycle configuration. 如图: 这表示m2e在其执行maven的生命周期管理时没有 ...

  9. 使用express.js框架一步步实现基本应用以及构建可扩展的web应用

    最近过年在家有点懈怠,但是自己也不断在学习新的前端技术,在家琢磨了express.js的web框架. 框架的作用就是提高开发效率,快速产出结果.即使不使用框架,我们也会在开发过程中逐渐形成构成框架. ...

  10. c#入门系列——类和对象的代码实现

    面向对象 说起面向对象,大家因该都听说过,也知道是一个编程的方法,简称oop技术.它将对象的算法和数据结构看作一个整体,而一个程序就是由多个对象结合的整体.这样做可以提高代码的复用率,提高了软件的可维 ...