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.");
    }
  }
}

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

(0)

相关推荐

  • C#中利用代理实现观察者设计模式详解

    界面开发中,经常使用观察者设计模式来实现文档/视图模式,当文档内容改变时,作为观察者的用户视图必须相应作出调整以向用户呈现文档的状态.由于语言机制的不同,观察者设计模式在不同的语言中实现方法也不尽相同. 在MFC的文档/视图模式中,每当文档内容改变都需要调用UpdateAllView函数来更新视图,该函数会遍历文档的每一个视图,调用每个视图的更新函数来更新视图,为此文档须登记每一个使用该文档的视图.C#中观察者设计模式的实现也可以采用这种方法,但C#提供的代理(delegate)机制为实现观察者

  • 浅谈C#设计模式之工厂模式

    工厂模式和简单工厂有什么区别.废话不多说,对比第一篇例子应该很清楚能看出来. 优点: 工厂模式弥补了简单工厂模式中违背开放-封闭原则,又保持了封装对象创建过程的优点. 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DesignModel {     public inte

  • C#设计模式之观察者模式实例讲解

    前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡"Design Pattern(设计模式)"? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻

  • 浅谈C#设计模式之代理模式

    代理模式是常用的结构型设计模式之一,当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口.根据代理模式的使用目的不同,代理模式又可以分为多种类型,例如保护代理.远程代理.虚拟代理.缓冲代理等,它们应用于不同的场合,满足用户的不同需求 复制代码 代码如下: using System; using System.Collections.Generic; using System.Linq; using

  • C#设计模式之单例模式实例讲解

    前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡"Design Pattern(设计模式)"? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻

  • 实例解析C#设计模式编程中简单工厂模式的使用

    简单工厂模式的介绍 说到简单工厂,自然的第一个疑问当然就是什么是简单工厂模式了? 在现实生活中工厂是负责生产产品的,同样在设计模式中,简单工厂模式我们也可以理解为负责生产对象的一个类, 我们平常编程中,当使用"new"关键字创建一个对象时,此时该类就依赖与这个对象,也就是他们之间的耦合度高,当需求变化时,我们就不得不去修改此类的源码,此时我们可以运用面向对象(OO)的很重要的原则去解决这一的问题,该原则就是--封装改变,既然要封装改变,自然也就要找到改变的代码,然后把改变的代码用类来封

  • 举例讲解C#编程中对设计模式中的单例模式的运用

    单例模式的介绍 说到单例模式,大家第一反应应该就是--什么是单例模式?,从"单例"字面意思上理解为--一个类只有一个实例,所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了,下面给出单例模式的一个官方定义:确保一个类只有一个实例,并提供一个全局访问点.为了帮助大家更好地理解单例模式,大家可以结合下面的类图来进行理解,以及后面也会剖析单例模式的实现思路: 为什么会有单例模式 看完单例模式的介绍,自然大家都会有这样一个疑问--为什么要有单例模式的?它在什么情况下使用的?从单例模式的

  • C#设计模式之外观模式介绍

    1.在设计初期阶段,应该要有意识的将不同的两层分离,比如考虑数据访问层.业务逻辑层.表示层之间建立外观模式,这样可以为子系统提供简单一致的接口,使得耦合大大降低. 2.开发阶段,子系统内部由于不够重构变得非常复杂,增加外观模式可以屏蔽这个复杂性,并提供简单的接口. 3.维护一个遗留的大型系统,代码不好再维护时,使用外观模式也是不错的选择. 看看外观模式的结构图: Facade类定义:可以给高层系统提供简单的接口 复制代码 代码如下: class Facade { SubSystemOne one

  • 浅谈c#设计模式之单一原则

    单一原则: 程序设计时功能模块独立,功能单一更有助于维护和复用. 例如:个人计算机功能很多,如果想从中只拿出一个功能来制造一个新的东西是困难的.同时如果你的计算机开不机,同时你的计算器功能也不能用了. 在编程中如果一个类封装了太多功能和上面的结果是类似的. 单一职责原则 例1: 大家应该能看出来这个类图中的接口设计是有问题的,用户的属性和用户的行为没有分开.我们根据用户的属性和行为拆开这个接口. 重新拆分成两个接口,IUserBo 负责用户的属性,IUserBiz负责用户的行为.当我们实例化除U

  • c#设计模式 适配器模式详细介绍

    后续内容将包括以下结构模式: 适配器模式(Adapter):Match interfaces of different classes合成模式(Composite):A tree structure of simple and composite objects装饰模式(Decorator):Add responsibilities to objects dynamically代理模式(Proxy):An object representing another object享元模式(Flywei

随机推荐