博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# - 设计模式 - 策略模式
阅读量:5823 次
发布时间:2019-06-18

本文共 1611 字,大约阅读时间需要 5 分钟。

策略模式

问题场景

多个类型都有一些共同的属性和方法,可以称这些成员为行为,为了避免重复在多个类型中编码相同部分的行为,应考虑将这些行为定义在抽象类(超类)中,利用继承时多个类型可以共享这些行为。比如定义一个超类Animal,具有Eyes属性和Run方法,老虎和狮子都从Animal派生,所以可以靠继承得到Animal定义的行为。但是今后需求变更,可能会增加一个袋鼠,袋鼠只会跳不会跑,所以当袋鼠也具备Run时就显得不合理。再次设计类型结构时,可能会考虑接口,比如将Run和Jump定义成接口IRunable和IJumpable,以插拔的形式插入需要这些行为的动物中。可是这样做,那么每一个动物都需要实现插拔在它们上面的接口所定义方法。所以继承没有使类型结构变得合理,而插拔也并没有防止重复编码的问题。现在可以考虑策略模式,行为接口IRun由独立的类型Run来实现,将Run作为需要奔跑行为的类型的一个属性进行存取,这样,Run类实现了奔跑的行为,所以需要奔跑行为的动物就不再需要重复编码奔跑行为,而是调用IRun类的实现就可以了。

总结模式

找出类型中的不易变化的行为和可能变化的行为,将可能在未来变化的行为提炼成独立的类型,这些独立的类型应该是行为接口的具体实现。也即,将未来易于变化和扩展的行为从类型中解构出去,分解为更为细小的接口的实现,当类型需要某种行为时只需要委托给接口的实现,由接口的实现来提供可变化的部分,这样就不会影响类型的结构,需求改动时,只需要更改接口实现的代码,而不需要在多个类型中修改代码,从而达到只在一处更改却多处受益的效果。也即,一个类型中不易变化的事物应该定义在类型中,否则提取出来定义成接口的实现。

示例代码

namespace AppCUI
{
    public interface IRun {
 void Run( ); }
    public class Run : IRun {
 void IRun.Run( ) {
 Console.WriteLine( "Run!" ); } }
    public class Animal
    {
        public string Name {
 get; set; }
        private IRun run;
        public void Run( )
        {
            run = new Run( ); //默认的IRun的实现
            run.Run( );
        }
        public void ChangeRun( IRun run ) //注入其它的IRun的实现,应对今后需求的改变
        {
            run.Run( );
        }
    }
    public class Tiger : Animal {
 }
    //狮子类需要奔跑,就将奔跑接口的实现作为属性存取,也即我需要奔跑这个行为,我委托给奔跑接口的实现为我提供奔跑的能力
    //羚羊类需要奔跑,就将奔跑接口的实现作为属性存取就可以了
    //100个类需要奔跑,也同样如此
    //以后要修改奔跑的行为,只需要修改Run类的Run方法,仅此一处需要修改,不用在多个动物中修改代码了
    //如果有更特殊的奔跑行为又如何?
    //只需要再定义一个SpecialRun类实现IRun就可以了!
    public class SpecialRun : IRun {
 void IRun.Run( ) {
 Console.WriteLine( "SpecialRun!" ); } }
    public class Programe
    {
        static void Main( string[] args )
        {
            Tiger tiger = new Tiger( );
            tiger.Run( );
            tiger.ChangeRun( new SpecialRun( ) );
        }
    }
}

  

转载于:https://www.cnblogs.com/myrocknroll/p/8596763.html

你可能感兴趣的文章
Linux下使用fdisk扩展分区容量
查看>>
Mesos+Marathon+zk+docker构建PaaS平台
查看>>
DataWorks2.0的“业务流程”与1.0的“工作流”的对比
查看>>
计算1-100之间数的和,计算其之间偶数的和
查看>>
299. Bulls and Cows - LeetCode
查看>>
Java抽象类
查看>>
在向HDFS中写数据的时候,当写某一副本时出错怎么处理?
查看>>
【Android Developer】1.一个关于Android机器人的故事
查看>>
模具常用术语中英文对照
查看>>
我管理的华为设备
查看>>
Ubuntu 11.10下安装google拼音
查看>>
稀疏矩阵的列序递增法和一次定位快速转置法
查看>>
在QTP中将WebTable的数据取出放入DataTable
查看>>
TCP传输协议抓包
查看>>
SVN服务搭建
查看>>
17款jQuery在线QQ客服代码分享
查看>>
Android ImageView使用网络资源文件
查看>>
让VIM记录文件上次编辑的位置
查看>>
Bootstrap V4 自学之路 文档目录
查看>>
基于NFS实现lamp的负载均衡之六: 部署discuz论坛
查看>>