当前位置: 移动技术网 > IT编程>开发语言>c# > C#设计模式之行为型模式详解

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

2019年07月18日  | 移动技术网IT编程  | 我要评论

这里列举行为型模式·到此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.");
    }
  }
}

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网