zoukankan      html  css  js  c++  java
  • C#

    策略模式

    问题场景

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

  • 相关阅读:
    团队博客-十日冲刺6
    04构建之法阅读笔记之一
    Java基础-面向对象三大特性
    剑指 Offer 38. 字符串的排列
    Java基础:包装类 装箱/拆箱 Integer
    剑指 Offer 34. 二叉树中和为某一值的路径
    LeetCode 树:105. 从前序与中序遍历序列构造二叉树
    Java基础:类型
    Java基础:值传递和引用传递
    数据结构:图的基本知识
  • 原文地址:https://www.cnblogs.com/myrocknroll/p/8596763.html
Copyright © 2011-2022 走看看