[.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++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...
随机推荐
- JTree实例
JTree实例 private void createTreeByXdDdt() { DefaultComboBoxModel boxModel = (DefaultComboBoxModel) cm ...
- Oracle 去掉重复字符串
create or replace function remove_same_string(oldStr varchar2, sign varchar2) return varchar2 is /** ...
- Cocos2d-x 多分辨率支持
最近遇到多分辨率支持问题,所以查了一些资料.将一些收获共享一下,以便自己和其他需要的朋友日后参考. 如果我要建立一个cocos2d-x项目,我的目标是支持iphone3G( 480, 320 ),ip ...
- Spring4.14 事务异常 NoUniqueBeanDefinitionException: No qualifying bean of type [....PlatformTransactionManager]
环境为Spring + Spring mvc + mybatis:其中Spring版本为4.1.4 spring配置文件: <?xml version="1.0" encod ...
- Word常用实用知识2
纯手打,可能有错别字,使用的版本是office Word 2013 转载请注明出处 http://www.cnblogs.com/hnnydxgjj/p/6296863.html,谢谢. 批注和 ...
- easyui treegrid实现显示checkbox并能获取到选定值的
闲聊: 小颖最近忙疯了,经常被加班,昨天都要下班了,又提了个需求,虽然写的代码不多只有几行,可是测试环境很难跑通,一会就ie崩溃了,所以弄得小颖最近老是头晕. 也不知道最近是怎么了,一向特别爱吃的小颖 ...
- cocos2dx内存管理的个人理解
1.一帧开始之后的过程中,将所有执行到的autorelease的对象加入到池中:2.一帧结束之前取出池中的所有对象记作objs,清空池:3.对取出来的objs进行遍历,每个元素进行一次release: ...
- hadoop系列一:hadoop集群安装
转载请在页首明显处注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6384393.html 一:说明 此为大数据系列的一些博文,有空的话会陆续更新,包含大数据 ...
- 矢量切片(Vector tile)
说明:本月的主要工作都是围绕制作矢量切片这一个核心问题进行的,所以2月的主题就以这个问题为主,目前分支出来的一些内容主要包括了TMS(Tile map service),OpenLayers3中的Pr ...
- 重新认识一个强大的 Gson
从一个 Bug 说起 不知道你们发现没有,你写完的程序无论当时怎么测试,过一段时间总会出 Bug .再说一个每天都在发生的例子:在你写完一篇博客后,立即检查的话,总是查不出自己写的错别字. 据说这些都 ...