策略模式

问题场景

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

    比较水的模拟 思路:就是模拟题意 注意:把数组开大点,开始wa了几次就是这个原因 #include<iostream> #include<string> #include< ...

  2. Python的dnspython库使用指南

    因为平时在测试DNS的时候有些操作手动完成不方便,所以需要用到脚本,而在Python里dnspython这个用于DNS操作的库十分强大,但是无奈网上大部分资料只列举了少部分的用法,所以记录一下我平时使 ...

  3. python scapy dns 包字段解析

    qr:   0表示查询报文,1表示响应报文opcode: 通常值为0(标准查询),其他值为1(反向查询)和2(服务器状态请求).aa: 表示授权回答(authoritative answer)tc: ...

  4. 对于for循环中使用let或var时,i的作用域范围的记录

    在for循环中使用let时,结果如下 for内部定义的i在循环结束后不会覆盖外部的i 在for循环中使用var,且不控制i的作用域时,结果如下 第一个for循环内部定义的i并不会创建,而是直接使用外部 ...

  5. Solving the Top ERP and CRM Metadata Challenges with erwin & Silwood

    Registrationhttps://register.gotowebinar.com/register/3486582555108619010 Solving the Top ERP and CR ...

  6. vscode在vue-cli中按照ESlint自动格式化代码

    先安装 1 npm i -S eslint-plugin-vue .eslintrc下 1 2 3 "plugins": [     "vue" ] vscod ...

  7. Clion设置字体大小和护眼色

    1.显示行号File->Settings->Editor->General->Appearance右侧,Show line numbers 2.设置字体大小与行间距File-& ...

  8. Python——Socket编程

    一.TCP 1.客户端 import socket sk = socket.socket() # 买个手机 sk.connect(('127.0.0.1',8080)) # 拨号 ret = sk.r ...

  9. ADT SDK Manager启动时一闪而过

    原因为使用了Android Studio的绿色JRE,必须要安装安装版JDK或者JRE,绿色版JRE放在ADT目录虽然能启动ADT但是不能启动SDK Manager

  10. 数据分析之Pandas

    一.Pandas介绍 1.介绍 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具. ...