策略模式

问题场景

多个类型都有一些共同的属性和方法,可以称这些成员为行为,为了避免重复在多个类型中编码相同部分的行为,应考虑将这些行为定义在抽象类(超类)中,利用继承时多个类型可以共享这些行为。比如定义一个超类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( ) );
        }
    }
}

  

C# - 设计模式目录

C# - 设计模式 - 策略模式的更多相关文章

  1. 15. 星际争霸之php设计模式--策略模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

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

    [.net 面向对象程序设计深入](24)实战设计模式——策略模式(行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它 ...

  3. linkin大话设计模式--策略模式

    linkin大话设计模式--策略模式 Strategy [ˈstrætədʒi]  策略 策略模式用于封装系列的算法,这些算法通常被封装在一个称为Context的类中,客户端程序可以自由的选择任何一种 ...

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

    [.net 面向对象程序设计深入](26)实战设计模式——策略模式 Strategy (行为型) 1,策略模式定义 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模 ...

  5. 设计模式-策略模式(Strategy Model)

    1.概述     在开发过程中常常会遇到类似问题,实现一个功能的时候往往有多种算法/方法(策略),我们可以根据环境的不同来使用不同的算法或策略来实现这一功能.     如在人物比较排序的实现中,我们有 ...

  6. java设计模式 策略模式Strategy

    本章讲述java设计模式中,策略模式相关的知识点. 1.策略模式定义 策略模式,又叫算法簇模式,就是定义了不同的算法族,并且之间可以互相替换,此模式让算法的变化独立于使用算法的客户.策略模式属于对象的 ...

  7. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  8. javascript 设计模式-----策略模式

    在<javascript设计模式>中,作者并没有向我们介绍策略模式,然而它却是一种在开发中十分常见的设计模式.最常见的就是当我们遇到一个复杂的表单验证的时候,常常需要编写一大段的if和el ...

  9. JAVA 设计模式 策略模式

    用途 Title 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 策略模式是一种行为型模式. 结构

  10. PHP设计模式-策略模式 转

    策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个 ...

随机推荐

  1. Notepad++设置背景色

    点击菜单“设置”-“语言格式设置” 在语言中,选中Global Styles,在样式栏选 中Default Style,再在右边点击背景色的颜色方块. 在打开的颜色对话框中点击 More Colour ...

  2. 【转】Android中保持Service的存活

    这几天一直在准备考试,总算有个半天时间可以休息下,写写博客. 如何让Service keep alive是一个很常见的问题. 在APP开发过程中,需要Service持续提供服务的应用场景太多了,比如闹 ...

  3. sql server 压缩数据库

    收缩日志 ALTER DATABASE 数据库名称 SET RECOVERY SIMPLEDBCC SHRINKDATABASE(数据库名称, 0) 压缩数据库ALTER DATABASE 数据库名称 ...

  4. zabbix,php,nginx,mysql源码安装 神仙操作

    →软件包 mkdir /soft/ cd /soft ♦下载以下软件包 nginx-1.14.2.tar.gz wget http://nginx.org/download/nginx-1.14.2. ...

  5. 步步深入:MySQL架构总览->查询执行流程->SQL解析顺序(转)

    文章转自   http://www.cnblogs.com/annsshadow/p/5037667.html https://www.cnblogs.com/cuisi/p/7685893.html

  6. Luogu P1852 BZOJ 2144 [国家集训队]跳跳棋

    qwq 这题一看就不会,如果不是gg让做我是坚决不会做的 画图模拟,因为一次只能跳过一个棋子,所以对于一种情况只有三种移动方式: 中间向左跳 中间向右跳 左或右(距中间近的那个)向中间跳 发现,除了跳 ...

  7. android9.0系统适配遇到的问题

    一.apk在9.0以下的系统上安装运行,没有问题.但是在9.0系统上运行会弹出一个框 解决办法: private void closeAndroidPDialog() { try { Class aC ...

  8. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  9. PySocks安装使用方法

    PySocks是一个基于Python的SOCKS代理客户端,它是SocksiPy的一个分支,修改了一些bug和增加了一些额外功能. ---------------------------------- ...

  10. ibatisNet MERGE INTO ORA-00911: 无效字符

    在sql工具中测试正常,放到代码中出现 “ORA-00911: 无效字符” 错误时,请检查sql语句是否有分号.