[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)
[.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)实战设计模式——策略模式(行为型)的更多相关文章
- [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...
- 24种设计模式-策略模式(Strategy Pattern)
一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...
- 24种设计模式--策略模式【Strategy Pattern】
刘备要到江东娶老婆了,走之前诸葛亮给赵云(伴郎)三个锦囊妙计,说是按天机拆开解决棘手问题,嘿,还别说,真是解决了大问题,搞到最后是周瑜赔了夫人有折兵呀,那咱们先看看这个场景是什么样子的. 先说这个场景 ...
- [.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下)
[.net 面向对象程序设计进阶] (24) 团队开发利器(三)使用SVN多分支并行开发(下) 本篇导读: 接上篇继续介绍SVN的高级功能,即使用分支并行开发.随着需求的不断变更,新功能的增加.特别是 ...
- PHP设计模式-策略模式 转
策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个 ...
- 15. 星际争霸之php设计模式--策略模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- 设计模式:Strategy 策略模式 -- 行为型
设计模式 策略模式Strategy(对象行为型) 这是几年前写的文字(转载做的笔记更准确些),发觉还是废话多了点. 其实,核心就是5.结构中的UML图 5.1 和 5.2(新增).现在看这张图就觉得一 ...
- linkin大话设计模式--策略模式
linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi] 策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...
- 面向对象设计模式--策略模式Strategy
策略模式的UML类图(VS2013 C++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...
随机推荐
- spring mvc 入门示例
classpath <?xml version="1.0" encoding="UTF-8"?> <classpath> <cla ...
- H.264转码加速:NVENC大战Quick Sync
GPU加速技术对普通消费者最直观的影响就是视频转码应用上了,NVIDIA..AMD以及Intel都有自己的加速技术,而在新一代CPU和GPU架构上,三方都有更新的技术方案.<br>< ...
- HDU1494(dp)
跑跑卡丁车 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Jcompress: 一款基于huffman编码和最小堆的压缩、解压缩小程序
前言 最近基于huffman编码和最小堆排序算法实现了一个压缩.解压缩的小程序.其源代码已经上传到github上面: Jcompress下载地址 .在本人的github上面有一个叫Utility的re ...
- linux pagecache与内存占用
实验环境 CentOS Linux release 7.3.1611 (Core) 3.10.0-514.6.1.el7.x86_64 一.概念介绍 linux系统中通常使用free命 ...
- cordova StatusBar插件的使用(设置手机状态栏颜色和页面头部颜色一致),做出和原生一样的页面效果体验
cordova StatusBar插件的使用(设置手机状态栏颜色和页面头部颜色一致),做出和原生一样的页面效果体验设置设备状态栏背景颜色StatusBar.backgroundColorByHexSt ...
- j2se 总结
j2se在学习第二遍的时候,感觉还是比较亲切的.
- phpcmsV9于基本介绍
1.phpcms做企业站 2.内容+管理栏目=页面显示的导航 3.文件目录结构 根目录 api 接口文件目录 caches 缓存文件目录 confings 系统配置文件目录 caches_*系统缓存目 ...
- 聊聊dmClock算法
作者:吴香伟 发表于 2017/01/08 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 人们常常容易忽略一些不起眼但特别重要的事物.曾经跟同事聊Python, ...
- [Hadoop] - 异常Cannot obtain block length for LocatedBlock
在Flume NG+hadoop的开发中,运行mapreduce的时候出现异常Error: java.io.IOException: Cannot obtain block length for Lo ...