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

摘要:
net面向对象深度编程实用设计模式-策略(行为)1。策略模式定义了一系列算法,封装了每个算法,并使它们可互换。-具体的战略角色:包装相关的算法和行为。当行为中存在多个条件时。允许用户在多个策略之间切换行为。很容易将策略中的各种行为暴露给用户。需要创建许多策略类。我们添加了BiShi()方法参数,改进后的代码如下:抽象策略类LunJian publicabstractclassLunJian{publicabstract voidBiSai;}特定策略类WaiGongNeiGongZhaoShippublicClassWaiGong:LunJian{publicoverriddoidBiSai{Console.WriteLine(“外部技能竞赛开始!

[.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类图

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

下面是具体代码:

 抽象策略类 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();
        }
    }

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

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

(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();
        }
    }

运行结果:

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

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

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

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

6,总结 

(1)策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
(2)在策略模式中,应当由客户端自己决定在什么情况下使用什么具体策略角色。

(3)策略模式仅仅封装算法,提供新算法插入到已有系统中,以及老算法从系统中“退休”的方便,策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。这在一定程度上提高了系统的灵活性,但是客户端需要理解所有具体策略类之间的区别,以便选择合适的算法,这也是策略模式的缺点之一,在一定程度上增加了客户端的使用难度。

7.实例源代码

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

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

返回目录

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

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

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

.NET 技术交流群:467189533H.NET 技术交流群

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

免责声明:文章转载自《[.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python 安装新的模块Wireshark——工具下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

从零开始学区块链(4)

转自:区块链大师 1. 传统分布式一致性算法和区块链共识过程的异同点 相同点: Append only(只能增加) 强调序列化 少数服从多数原则 分离覆盖的问题:即长链覆盖短链区块,多节点覆盖少数节点日志 不同点: 传统分布式一致性算法大多不考虑拜占庭容错(Byzanetine Paxos除外),即假设所有节点只发生宕机、网络故障等非人为问题,并不考...

OpenCV白平衡算法之灰度世界法(消除RGB受光照影响)

在用OpenCV对图像进行处理时,利用颜色定位是常常会接触到的方法,但RGB受光照影响比较严重,转换到HSV XYZ等空间也解决不了时, 可以用白平衡算法进行修正,使其发黄、发蓝、发红的照片更加趋于自然光下的图像。(转摘请说明来源) 程序代码示例如下: 1 //该代码实现白平衡算法中的灰度世界法,能有效改善图像发红发蓝发绿的现象; 2 3 #includ...

验证码识别,发票编号识别

update:排版 这个demo的初衷不是去识别验证码,是把验证的图像处理方式用到其他方面,车票,票据等。 这里最后做了一个发票编号识别的的案例: 地址:http://v.youku.com/v_show/id_XMTI1MzUxNDY3Ng==.html 源代码:https://github.com/ccccccmd/ReCapcha demo中包含一个...

全同态加密算法

摘要本文主要讲述完全同态加密算法。1. 是什么?同态加密是一种对称加密算法,由Craig Gentry发明提出。其同态加密方案包括4个算法,即密钥生成算法、加密算法、解密算法和额外的评估算法。全同态加密包括两种基本的同态类型,即乘法同态和加法同态,加密算法分别对乘法和加法具备同态特性。2. 算法的原理全同态加密的原理:如果E为针对function_a的全同...

第十三节、SURF特征提取算法

上一节我们已经介绍了SIFT算法,SIFT算法对旋转、尺度缩放、亮度变化等保持不变性,对视角变换、仿射变化、噪声也保持一定程度的稳定性,是一种非常优秀的局部特征描述算法。但是其实时性相对不高。 SURF(Speeded Up Robust Features)算法改进了特征了提取和描述方式,用一种更为高效的方式完成特征点的提取和描述。 一 使用快速Hessi...

OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分析与比较

KAZE系列笔记:1.OpenCV学习笔记(27)KAZE 算法原理与源码分析(一)非线性扩散滤波 2.OpenCV学习笔记(28)KAZE 算法原理与源码分析(二)非线性尺度空间构建 3.OpenCV学习笔记(29)KAZE 算法原理与源码分析(三)特征检测与描述 4.OpenCV学习笔记(30)KAZE 算法原理与源码分析(四)KAZE特征的性能分...