好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

C#设计模式之行为型模式详解

这里列举行为型模式·到此23种就列完了···这里是看着菜鸟教程来实现··,他里边列了25种,其中过滤器模式和空对象模式应该不属于所谓的23种模式

责任链模式:为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦,大部分用于web中吧。。
Task中的continuewith和微软的tpl数据流应该是类似这种模式的实现吧

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

//责任链模式

namespace ExercisePrj.Dsignmode

{

   public abstract class AbstractLogger

   {

     public static int INFO = 1;

     public static int DEBUG = 2;

     public static int ERROR = 3;

     protected int level;

     //责任链中的下一个对象

     protected AbstractLogger nextLogger;

     public void SetNextLogger(AbstractLogger next)

     {

       nextLogger = next;

     }

     public void LogMessage( int level, string message)

     {

       if ( this .level<=level)

       {

         Write(message);

       }

       if (nextLogger!= null )

       {

         nextLogger.LogMessage(level, message);

       }

     }

     protected abstract void Write( string message);

   }

   public class ConsoleLogger : AbstractLogger

   {

 

     public ConsoleLogger( int level)

     {

       this .level = level;

     }

 

     protected override void Write( string message)

     {

       Console.WriteLine( "Standard Console::Logger: " + message);

     }

   }

   public class ErrorLogger : AbstractLogger

   {

 

     public ErrorLogger( int level)

     {

       this .level = level;

     }

 

     protected override void Write(String message)

     {

       Console.WriteLine( "Error Console::Logger: " + message);

     }

   }

   public class FileLogger : AbstractLogger

   {

     public FileLogger( int level)

     {

       this .level = level;

     }

 

     protected override void Write(String message)

     {

       Console.WriteLine( "File::Logger: " + message);

     }

   }

}

命令模式(Command Pattern):请求以命令的形式执行,CAD的的命令应该就是以这种方式执行的·二次开发的时候通过特性标识和继承他的接口来添加命令,非常方便

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

//命令模式

namespace ExercisePrj.Dsignmode

{

   public interface IOrder

   {

     void Execute();

   }

   public class Stock

   {

     private string name = "ABC" ;

     private int quantity = 10;

 

     public void Buy()

     {

       Console.WriteLine( "Stock name:{0},quantity:{1},bought" ,name,quantity);

     }

     public void Sell()

     {

       Console.WriteLine( "Stock name:{0},quantity:{1}sold" , name, quantity);

     }

   }

   //请求类

   public class BuyStock : IOrder

   {

     private Stock abcStock;

 

     public BuyStock(Stock abcStock)

     {

       this .abcStock = abcStock;

     }

 

     public void Execute()

     {

       abcStock.Buy();

     }

   }

   //继承接口的实体

   public class SellStock : IOrder

   {

     private Stock abcStock;

 

     public SellStock(Stock abcStock)

     {

       this .abcStock = abcStock;

     }

 

     public void Execute()

     {

       abcStock.Sell();

     }

   }

 

   //命令调用类

   public class Broker

   {

     private List<IOrder> orderList = new List<IOrder>();

 

     public void takeOrder(IOrder order)

     {

       orderList.Add(order);

     }

 

     public void placeOrders()

     {

       foreach (IOrder order in orderList)

       {

         order.Execute();

       }

       orderList.Clear();

     }

   }

 

}

解释器模式:就是实现一种表达式接口,C#的各种表达式就是这种实现吧··这玩意跟富文本编辑器一样是个大坑吧··,做好了确实很好使,一不小心就得跪

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

//解释器模式

namespace ExercisePrj.Dsignmode

{

   public interface Expression

   {

      bool Interpret( string context);

   }

   public class TerminalExpression : Expression

   {

     private string data;

 

     public TerminalExpression( string data)

     {

       this .data = data;

     }

 

     public bool Interpret( string context)

     {

       if (context.Contains(data))

       {

         return true ;

       }

       return false ;

     }

   }

   public class OrExpression : Expression

   {

     private Expression expr1 = null ;

     private Expression expr2 = null ;

     public OrExpression(Expression expr1, Expression expr2)

     {

       this .expr1 = expr1;

       this .expr2 = expr2;

     }

     public bool Interpret(String context)

     {

       return expr1.Interpret(context) || expr2.Interpret(context);

     }

   }

   public class AndExpression : Expression

   {

     private Expression expr1 = null ;

     private Expression expr2 = null ;

 

     public AndExpression(Expression expr1, Expression expr2)

     {

       this .expr1 = expr1;

       this .expr2 = expr2;

     }

     public bool Interpret(String context)

     {

       return expr1.Interpret(context) && expr2.Interpret(context);

     }

     }

}

迭代器模式(Iterator Pattern):.NET自带接口···,直接实现就行了··注意又泛型接口和非泛型接口··非泛型接口迭代对象返回的是object,泛型接口返回的直接就是对象了,还有通过yield的简化写法不用额外去实现IEnumerator接口

?

using System;

using System.Collections;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public class IteratorEx : IEnumerable //<IteratorEx>

   {

     public string Name;

     private List<IteratorEx> list = new List<IteratorEx>();

 

     //public IEnumerator<IteratorEx> GetEnumerator()

     //{

     //  foreach (var l in list)

     //  {

     //    yield return l;

     //  }

     //}

 

     public void SetList(List<IteratorEx> data)

     {

       list = data;

     }

 

     IEnumerator IEnumerable.GetEnumerator()

     {

       foreach (var l in list)

       {

         yield return l;

       }

       //return new IteratorExEnum(list.ToArray());

     }

   }

   public class IteratorExEnum : IEnumerator

   {

     private IteratorEx[] list;

     private int position = -1;

     public IteratorExEnum(IteratorEx[] data)

     {

       list = data;

     }

     public object Current

     {

       get

       {

         try

         {

           return list[position];

         }

         catch (IndexOutOfRangeException)

         {

           throw new InvalidOperationException();

         }

       }

     }

 

     public bool MoveNext()

     {

       position++;

       return position < list.Length;

     }

 

     public void Reset()

     {

       position = -1;

     }

   }

 

}

中介者模式(Mediator Pattern):用一个中介对象封装一些对象的交互,中介者使对象不用显式的互相引用,MVC和mvp 的c和p都是类似这玩意的实现吧

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   //中介类

   public class ChatRoom

   {

     public static void ShowMessage(User user, string msg)

     {

       Console.WriteLine( new DateTime().ToString()+ "[" + user.Name + "] : " + msg);

     }

   }

   public class User

   {

     public string Name { get ; set ; }

 

     public User( string name)

     {

       Name = name;

     }

 

     public void SendMessage(String message)

     {

       ChatRoom.ShowMessage( this , message);

     }

   }

 

 

}

备忘录模式(Memento Pattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存,

大部分支持回退的操作场景下应该都是这种模式··之前做的软件中有画图的操作···支持后退,实现方式非常简单粗暴··,直接吧图层的画图对象克隆一份保存··只支持5还是10步,讲道理这么实现确实有点那啥了···

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public class Memento

   {

     public string State { get ; }

     public Memento( string state)

     {

       State = state;

     }

   }

   public class Originator

   {

     public string State { get ; set ; }

 

     public Memento SaveStateToMemento()

     {

       return new Memento(State);

     }

 

     public void GetStateFromMemento(Memento Memento)

     {

       State = Memento.State;

     }

   }

   public class CareTaker

   {

     private List<Memento> mementoList = new List<Memento>();

 

     public void Add(Memento state)

     {

       mementoList.Add(state);

     }

 

     public Memento Get( int index)

     {

       return mementoList[index];

     }

   }

 

}

观察者模式(Observer Pattern):.net自带的有接口提供来实现观察者模式···这里照着msdn来实现一遍,自带的接口里边还实现了资源的释放··,之前并发编程里边的rx也是这个模式的具体实现·

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

//观察者模式

namespace ExercisePrj.Dsignmode

{

 

   public class Subject: IObservable<Subject>

   {

     public int State { get ; set ;}

     public Subject( int state)

     {

       State = state;

     }

     private List<IObserver<Subject>> observers = new List<IObserver<Subject>>();

 

     public IDisposable Subscribe(IObserver<Subject> observer)

     {

       if (!observers.Contains(observer))

         observers.Add(observer);

       return new Unsubscriber(observers, observer);

     }

     private class Unsubscriber : IDisposable

     {

       private List<IObserver<Subject>> _observers;

       private IObserver<Subject> _observer;

 

       public Unsubscriber(List<IObserver<Subject>> observers, IObserver<Subject> observer)

       {

         this ._observers = observers;

         this ._observer = observer;

       }

 

       public void Dispose()

       {

         if (_observer != null && _observers.Contains(_observer))

           _observers.Remove(_observer);

       }

     }

 

     public void TrackLocation(Subject ob)

     {

       Console.WriteLine( "start" );

       foreach (var observer in observers)

       {

         if (ob== null )

           observer.OnError( new Exception( "unknowExeption" ));

         else

           observer.OnNext(ob);

       }

     }

 

     public void EndTransmission()

     {

       foreach (var observer in observers.ToArray())

         if (observers.Contains(observer))

           observer.OnCompleted();

 

       observers.Clear();

     }

 

   }

 

 

   public class BinaryObserver : IObserver<Subject>

   {

     public void OnCompleted()

     {

       Console.WriteLine( "complete" );

     }

 

     public void OnError(Exception error)

     {

       Console.WriteLine(error.Message);

     }

 

     public void OnNext(Subject value)

     {

       Console.WriteLine( "Binary String: " + Convert.ToString(value.State, 2));

     }

   }

   public class OctalObserver : IObserver<Subject>

   {

     public void OnCompleted()

     {

       Console.WriteLine( "complete" );

     }

 

     public void OnError(Exception error)

     {

       Console.WriteLine(error.Message);

     }

 

     public void OnNext(Subject value)

     {

       Console.WriteLine( "Octal String: " + Convert.ToString(value.State, 8));

     }

 

   }

   public class HexaObserver : IObserver<Subject>

   {

     public void OnCompleted()

     {

       Console.WriteLine( "complete" );

     }

 

     public void OnError(Exception error)

     {

       Console.WriteLine(error.Message);

     }

 

     public void OnNext(Subject value)

     {

       Console.WriteLine( "Hex String: " + Convert.ToString(value.State,16));

     }

   }

}

状态模式(State Pattern):当对象内部状态发生改变时,行为也跟着改变

这个模式是为了解决类里边的大量if和swicth语句,讲道理例子写的有点怪···主体是context

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public class Context

   {

     public State State { get ; set ; }

 

     public Context()

     {

       State = null ;

     }

   }

   public interface State

   {

      void DoAction(Context context);

   }

 

   public class StartState : State

   {

     public void DoAction(Context context)

     {

       Console.WriteLine( "Player is in start state" );

       context.State = this ;

     }

 

     public override string ToString()

     {

       return "Start State" ;

     }

   }

   public class StopState : State

   {

 

     public void DoAction(Context context)

     {

       Console.WriteLine( "Player is in stop state" );

       context.State = this ;

     }

 

     public override string ToString()

     {

       return "Stop State" ;

     }

   }

}

空对象模式(Null Object Pattern):就是吧对空值的判断定义一个啥也不做的实体对象出来··C#的Nullable就是这个的实现···这玩意不在23种设计模式里边···

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public abstract class AbstractCustomer

   {

     public abstract bool IsNull();

     public abstract string Name { get ; }

   }

   public class RealCustomer : AbstractCustomer

   {

     public override string Name { get ; }

 

     public RealCustomer( string name)

     {

       Name = name;

     }

     public override bool IsNull()

     {

       return false ;

     }

   }

   public class NullCustomer : AbstractCustomer

   {

       public override string Name { get { return "Not Available in Customer Database" ; } }

       public override bool IsNull()

       {

         return true ;

       }

   }

   public class CustomerFactory

   {

     public static string [] names = { "Rob" , "Joe" , "Julie" };

      public static AbstractCustomer getCustomer( string name)

     {

       if (names.Contains(name))

       {

         return new RealCustomer(name);

       }

       return new NullCustomer();

     }

   }

}

策略模式(Strategy Pattern):定义一系列算法,封装成类,可以相互替换,通过构造不同的类,执行不同的操作。这样做方便调用,添加新的算法也方便,

最后加了自己之前对这个模式的奇葩写法

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public interface IStrategy

   {

      int DoOperation( int num1, int num2);

   }

   public class OperationAdd : IStrategy

   {

    

     public int DoOperation( int num1, int num2)

     {

       return num1 + num2;

     }

   }

 

   public class OperationSubstract : IStrategy

   {

 

     public int DoOperation( int num1, int num2)

     {

       return num1 - num2;

     }

   }

   public class OperationMultiply : IStrategy

   {

 

     public int DoOperation( int num1, int num2)

     {

        return num1 * num2;

     }

   }

 

   public class ContextEx

   {

     private IStrategy strategy;

 

     public ContextEx(IStrategy strategy)

     {

       this .strategy = strategy;

     }

 

     public int ExecuteStrategy( int num1, int num2)

     {

       return strategy.DoOperation(num1, num2);

     }

 

     //奇葩的写法简单粗暴

     private Dictionary< string , Func< int , int , int >> funcs = new Dictionary< string , Func< int , int , int >>();

     public int ExecuteStrategy( string name, int num1, int num2)

     {

       if (funcs.Count==0)

       {

         //反射写法

         var assembly = Assembly.GetExecutingAssembly();

         var types = assembly.GetTypes();

         foreach (var t in types)

         {

           if (t.GetInterface( "IStrategy" ) != null )

           {

             var instance = assembly.CreateInstance(t.FullName) as IStrategy;

             funcs.Add(t.Name, instance.DoOperation);

           }

         }

         //直接添加

         //funcs.Add("OperationAdd", new Func<int, int, int>((n1, n2) => { return n1 + n2; }));

         //funcs.Add("OperationSubstract", new Func<int, int, int>((n1, n2) => { return n1 - n2; }));

         //funcs.Add("OperationMultiply", new Func<int, int, int>((n1, n2) => { return n1 * n2; }));

       }

       return funcs[name](num1, num2);

     }

 

 

   }

}


模板模式(Template Pattern):.net的泛型就是这个模式的实现吧··照着模子写就行了

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

   public abstract class Game

   {

     public abstract void Initialize();

     public abstract void StartPlay();

     public abstract void EndPlay();

 

     //模板

     public void play()

     {

 

       //初始化游戏

       Initialize();

       //开始游戏

       StartPlay();

       //结束游戏

       EndPlay();

     }

   }

   public class Cricket : Game

   {

     public override void EndPlay()

     {

       Console.WriteLine( "Cricket Game Finished!" );

     }

 

     public override void Initialize()

     {

       Console.WriteLine( "Cricket Game Initialized! Start playing." );

     }

 

 

     public override void StartPlay()

     {

       Console.WriteLine( "Cricket Game Started. Enjoy the game!" );

     }

   }

}

访问者模式(Visitor Pattern):在被访问的类里边加一个对外提供接待访问的接口
把数据结构和对应的操作分开·添加操作很容易,但是如果结构变化多的化,改起来就麻烦了··
没研究没用过····

?

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

 

namespace ExercisePrj.Dsignmode

{

 

   public interface IComputerPartVisitor

   {

     void Visit(Computer computer);

     void Visit(Mouse mouse);

     void Visit(Keyboard keyboard);

     void Visit(Monitor monitor);

   }

 

   public interface IComputerPart

   {

     void Accept(IComputerPartVisitor computerPartVisitor);

   }

 

   public class Keyboard : IComputerPart

   {

 

     public void Accept(IComputerPartVisitor computerPartVisitor)

     {

       computerPartVisitor.Visit( this );

     }

   }

   public class Monitor : IComputerPart

   {

 

     public void Accept(IComputerPartVisitor computerPartVisitor)

     {

       computerPartVisitor.Visit( this );

     }

}

   public class Mouse : IComputerPart

   {

     public void Accept(IComputerPartVisitor computerPartVisitor)

     {

       computerPartVisitor.Visit( this );

     }

   }

   public class Computer : IComputerPart

   {

     IComputerPart [] parts;

     public Computer()

     {

       parts = new IComputerPart[] { new Mouse(), new Keyboard(), new Monitor() };

     }

     public void Accept(IComputerPartVisitor computerPartVisitor)

     {

       for ( int i = 0; i < parts.Length; i++)

       {

         parts[i].Accept(computerPartVisitor);

       }

       computerPartVisitor.Visit( this );

     }

   }

 

   public class ComputerPartDisplayVisitor : IComputerPartVisitor

   {

     public void Visit(Computer computer)

     {

       Console.WriteLine( "Displaying Computer." );

     }

     public void Visit(Mouse mouse)

     {

       Console.WriteLine( "Displaying Mouse." );

     }

     public void Visit(Keyboard keyboard)

     {

       Console.WriteLine( "Displaying Keyboard." );

     }

     public void Visit(Monitor monitor)

     {

       Console.WriteLine( "Displaying Monitor." );

     }

   }

}

 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

dy("nrwz");

查看更多关于C#设计模式之行为型模式详解的详细内容...

  阅读:39次