鸭子应用--策略模式
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
abstract class Strategy { // Methods abstract public void AlgorithmInterface(); } // "ConcreteStrategyA" class ConcreteStrategyA : Strategy { // Methods override public void AlgorithmInterface() { Console.WriteLine("Called ConcreteStrategyA.AlgorithmInterface()"); } } // "ConcreteStrategyB" class ConcreteStrategyB : Strategy { // Methods override public void AlgorithmInterface() { Console.WriteLine("Called ConcreteStrategyB.AlgorithmInterface()"); } } // "Context" class Context { // Fields Strategy strategy; // Constructors public Context(Strategy strategy) { this.strategy = strategy; } // Methods public void ContextInterface() { strategy.AlgorithmInterface(); } } /// <summary> /// Client test /// </summary> public class Client { public static void Main(string[] args) { // Three contexts following different strategies Context c = new Context(new ConcreteStrategyA()); c.ContextInterface(); } }
using System; namespace ConsoleApplication1 { #region 继承实现 public class Duck { public void Quack() { Console.WriteLine("Quack"); } public virtual void DisPlay() { Console.WriteLine("DisPlay"); } } public class MallardDuck : Duck { public override void DisPlay() { Console.WriteLine("green"); } } public class RedHeadDuck : Duck { public override void DisPlay() { Console.WriteLine("red"); } } public class RubberDuck : Duck { public override void DisPlay() { Console.WriteLine("black"); } } /* 新需求:需要加入Fly方法,但RubberDuck不应该有Fly的属性 * 新需求:需要加入新的Duck种类DecoyDuck,但DecoyDuck不会飞也不会叫*/ /*问题 * 代码在多个子类中重复 * 新增加的Duck很难预知其行为 * 运行时的行为不容易改变 * 牵一发动全身*/ #endregion #region 接口实现 public class Duck1 { public void Quack() { Console.WriteLine("Quack"); } public virtual void DisPlay() { Console.WriteLine("DisPlay"); } } public interface IFly { void Fly(); } public class MallardDuck1 : Duck1, IFly { public override void DisPlay() { Console.WriteLine("green"); } public void Fly() { Console.WriteLine("MallardFly"); } } public class RedHeadDuck1 : Duck1, IFly { public override void DisPlay() { Console.WriteLine("red"); } public void Fly() { Console.WriteLine("RedHeadFly"); } } public class RubberDuck1 : Duck1 { public override void DisPlay() { Console.WriteLine("black"); } } /* 多种Duck实现IFly内的Fly接口都要编写相关Fly的代码,相同的Fly功能代码无法重用。 */ #endregion #region 优化 /* 方案 * 多个Duck相同代码的提取重复利用 * 将变化的功能(Fly)提取成单独的行为实现类 * 运行时可以动态的赋予Duck的Fly类型 */
/* 这例子真是绝了。。。Duck2基类里有IFlyBehavior接口。。。不会飞的鸭子继承了,看起来是什么鬼样子。。。 */
public class Duck2 { public void Quack() { Console.WriteLine("Quack"); } public virtual void DisPlay() { Console.WriteLine("Black"); } public IFlyBehavior m_flyBehavior; public void FlyPerform() { m_flyBehavior.Fly(); } } // 行为类 public interface IFlyBehavior { void Fly(); } public class FlyBehaviorA : IFlyBehavior { public void Fly() { Console.WriteLine("FlyA"); } } public class FlyBehaviorB : IFlyBehavior { public void Fly() { Console.WriteLine("FlyB"); } } public class MallardDuck2 : Duck2 { public MallardDuck2(IFlyBehavior iFly) { m_flyBehavior = iFly; } public override void DisPlay() { Console.WriteLine("green"); } } public class RedHeadDuck2 : Duck2 { public RedHeadDuck2(IFlyBehavior iFly) { m_flyBehavior = iFly; } public override void DisPlay() { Console.WriteLine("red"); } } public class RubberDuck2 : Duck2 { public override void DisPlay() { base.DisPlay(); } } #endregion class DuckFactory { public enum DuckType { MALLARD, REDHEAD, RUBBER } public static Duck2 CreateDuck(DuckType type) { switch (type) { case DuckType.MALLARD: return new MallardDuck2(new FlyBehaviorA()); case DuckType.REDHEAD: return new RedHeadDuck2(new FlyBehaviorB()); case DuckType.RUBBER: return new RubberDuck2(); default: Console.WriteLine("Type Error..................."); return null; } } } class Program { static void Main(string[] args) { Duck2 mallard = DuckFactory.CreateDuck(DuckFactory.DuckType.MALLARD); mallard.m_flyBehavior.Fly(); Console.ReadKey(); } } }