[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)
[.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 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)的更多相关文章
- [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型)
[.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...
- 设计模式 - 策略模式(Strategy Pattern) 具体解释
策略模式(Strategy Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26577879 本文版权全 ...
- 设计模式--策略模式(strategy)
1.策略模式(strategy ['strætədʒi]) 我的理解是:方案候选模式 (反正关键就是有很多的候选,哈哈) 看了很多例子,都是在说鸭子的,那个例子很好,在这里可以看 他们生产鸭子,我们就 ...
- 面向对象设计模式--策略模式Strategy
策略模式的UML类图(VS2013 C++版本): 策略模式的重点:每个策略对象封装一个算法,有多少个算法就有多少个对象.策略模式的意图是封装算法.要从“抽象不仅面对状态(字段.属性)还面对行为(算法 ...
- 24种设计模式-策略模式(Strategy Pattern)
一.优点: 1. 策略模式提供了管理相关的算法族的办法.策略类的等级结构定义了一个算法或行为族.恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码. 2. 策略模式提供了可以替换继承关系的 ...
- java设计模式 策略模式Strategy
本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...
- 设计模式-策略模式Strategy以及消灭if else
概述 如果在开发过程中,出现大量的if else或者switch case 语句,如果这些语句块中的代码并不是包含业务逻辑,只是单纯的分流方法,那么,每一个语句块中都是一个算法或者叫策略. 背景 比如 ...
- 设计模式——策略模式(Strategy Pattern)
写在前面: 直接将书中的例子用来作为记录自己学习的成果,不知道这样好不好,如果给原作者带来什么不利的影响不妨告知一声,我及时删掉. UML图: 抽象策略:Strategy package com.cn ...
- 说说设计模式~策略模式(Strategy)
返回目录 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.而对于客户端(UI)来说,可以通过IOC再配合工厂模块,实现动态策略的切换,策略模块通常于一个抽象策略对象(in ...
随机推荐
- 如果没有<form>标签,也没有enctype="multipart/form-data"属性,怎么使用formData对象提交表单呢?如下方式
form标签的enctype属性 enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码. 默认地,表单数据会编码为 "application/x-www-form-urlen ...
- Vue过滤器使用
格式(一个过滤器):{{ 'msg' | filterA }} (多个过滤器):{{ 'msg' | filterA | filterB }} window.onload =function(){ / ...
- vue -- style使用scss样式报错
1.报错信息 2.解决方案(vue-li默认没有scss-loader,scss-loader)安装以下依赖 (1) npm install node-sass --save (2)npm insta ...
- JS & JQuery 动态处理select option
原文 出处http://www.51xuediannao.com/html+css/htmlcssjq/cssbuhuanhang.html 今天你问了我一个关于在<select>里动态添 ...
- c++ 开源库介绍和安装
1 BLAS库 BLAS(Basic Linear Algebra Subprograms)是一组线性代数计算中通用的基本运算操作函数集合.BLAS Technical (BLAST) Forum负责 ...
- main方法启动spring
main方式读取spring配置.main方法启动spring/ 有时候只想写一下简单的测试用一下. 新建一个maven项目 依赖pom <?xml version="1.0" ...
- Tomcat映射路径
打开tomcat安装包,在config目录下修改server.xml文件: 在<Host>标签中添加: <Context path="" docBase=&quo ...
- Web 性能优化:21 种优化 CSS 和加快网站速度的方法
这是 Web 性能优化的第 4 篇,上一篇在下面看点击查看: Web 性能优化:使用 Webpack 分离数据的正确方法 Web 性能优化:图片优化让网站大小减少 62% Web 性能优化:缓存 Re ...
- tp5 mkdir(): Permission denied 问题
今天使用tp5 线上上传图片的时候遇到了一个问题 mkdir(): Permission denied 如图 百度了一下 发现大家都说 chmod -R 777 runtime 能解决问题 尝试了一下 ...
- ASP.NET Aries 开发框架(已支持.NET Core)
背景: 当年,在卖弄与开源QBlog时,也曾想过把QBlog的开发理念整理整理,独立一个框架来开源. 不过,人越长大就越憔悴,激情终敌不过疲惫的惰性,最终无痕而终,连3.0的版本也没开源出来. 关于框 ...