策略模式

问题场景

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

    一.引言 Jenkins 2.0的到来,pipline进入了视野,jenkins2.0的核心特性. 也是最适合持续交付的feature. 简单的来说,就是把Jenkins1.0版本中,Project中 ...

  2. [LeetCode] 12,13 整数和罗马数互转

    12. 整数转罗马数字 题目链接:https://leetcode-cn.com/problems/integer-to-roman/ 题目描述: 罗马数字包含以下七种字符: I, V, X, L,C ...

  3. Chrome Inspect调试微信出现404,需要FQ

    要么FQ,要么买个程序 见连接 http://www.cnblogs.com/slmk/p/7591126.html

  4. eclipse 创建springboot项目

    eclipse创建springboot项目的三种方法: 引自:https://blog.csdn.net/mousede/article/details/81285693

  5. Raft与MongoDB复制集协议比较

    在一文搞懂raft算法一文中,从raft论文出发,详细介绍了raft的工作流程以及对特殊情况的处理.但算法.协议这种偏抽象的东西,仅仅看论文还是比较难以掌握的,需要看看在工业界的具体实现.本文关注Mo ...

  6. System.nanoTime与System.currentTimeMillis的区别(转)

    原文地址:http://blog.csdn.net/dliyuedong/article/details/8806868 平时产生随机数时我们经常拿时间做种子,比如用System.currentTim ...

  7. 播放器更改语言归属地后Cnario player软件无法启动的问题

    打开系统运行,输入regedit,进入注册表编辑器. 找到HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\C-nario\Player下面culture 的值,删除即可 ...

  8. CodeForces Round #552 Div.3

    A. Restoring Three Numbers 代码: #include <bits/stdc++.h> using namespace std; ]; int a, b, c; i ...

  9. 第六章· Redis高可用sentinel

    sentinel介绍 sentinel实战及配置讲解 sentinel介绍 什么是sentinel? Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Mas ...

  10. Linux(Ubuntu)使用日记(三)------git安装使用

    1. 安装 首先,确认你的系统是否已安装git,可以通过git指令进行查看,如果没有,在命令行模式下输入sudo apt-get install git命令进行安装. 2.  配置 git confi ...