欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-14 19:15:46
这里列举行为型模式·到此23种就列完了···这里是看着菜鸟教程来实现··,他里边列了25种,其中过滤器模式和空对象模式应该不属于所谓的23种模式 责任链模式:为请求创...

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

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

上一篇:

下一篇: