查看: 301|回复: 0

[ASP.NET教程] C#设计模式之行为型模式详解

发表于 2018-2-10 08:00:07

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. //责任链模式
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public abstract class AbstractLogger
  10. {
  11. public static int INFO = 1;
  12. public static int DEBUG = 2;
  13. public static int ERROR = 3;
  14. protected int level;
  15. //责任链中的下一个对象
  16. protected AbstractLogger nextLogger;
  17. public void SetNextLogger(AbstractLogger next)
  18. {
  19. nextLogger = next;
  20. }
  21. public void LogMessage(int level,string message)
  22. {
  23. if(this.level<=level)
  24. {
  25. Write(message);
  26. }
  27. if(nextLogger!=null)
  28. {
  29. nextLogger.LogMessage(level, message);
  30. }
  31. }
  32. protected abstract void Write(string message);
  33. }
  34. public class ConsoleLogger : AbstractLogger
  35. {
  36. public ConsoleLogger(int level)
  37. {
  38. this.level = level;
  39. }
  40. protected override void Write(string message)
  41. {
  42. Console.WriteLine("Standard Console::Logger: " + message);
  43. }
  44. }
  45. public class ErrorLogger : AbstractLogger
  46. {
  47. public ErrorLogger(int level)
  48. {
  49. this.level = level;
  50. }
  51. protected override void Write(String message)
  52. {
  53. Console.WriteLine("Error Console::Logger: " + message);
  54. }
  55. }
  56. public class FileLogger : AbstractLogger
  57. {
  58. public FileLogger(int level)
  59. {
  60. this.level = level;
  61. }
  62. protected override void Write(String message)
  63. {
  64. Console.WriteLine("File::Logger: " + message);
  65. }
  66. }
  67. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. //命令模式
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public interface IOrder
  10. {
  11. void Execute();
  12. }
  13. public class Stock
  14. {
  15. private string name = "ABC";
  16. private int quantity = 10;
  17. public void Buy()
  18. {
  19. Console.WriteLine("Stock name:{0},quantity:小贝,bought",name,quantity);
  20. }
  21. public void Sell()
  22. {
  23. Console.WriteLine("Stock name:{0},quantity:小贝sold", name, quantity);
  24. }
  25. }
  26. //请求类
  27. public class BuyStock : IOrder
  28. {
  29. private Stock abcStock;
  30. public BuyStock(Stock abcStock)
  31. {
  32. this.abcStock = abcStock;
  33. }
  34. public void Execute()
  35. {
  36. abcStock.Buy();
  37. }
  38. }
  39. //继承接口的实体
  40. public class SellStock : IOrder
  41. {
  42. private Stock abcStock;
  43. public SellStock(Stock abcStock)
  44. {
  45. this.abcStock = abcStock;
  46. }
  47. public void Execute()
  48. {
  49. abcStock.Sell();
  50. }
  51. }
  52. //命令调用类
  53. public class Broker
  54. {
  55. private List<IOrder> orderList = new List<IOrder>();
  56. public void takeOrder(IOrder order)
  57. {
  58. orderList.Add(order);
  59. }
  60. public void placeOrders()
  61. {
  62. foreach (IOrder order in orderList)
  63. {
  64. order.Execute();
  65. }
  66. orderList.Clear();
  67. }
  68. }
  69. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. //解释器模式
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public interface Expression
  10. {
  11. bool Interpret(string context);
  12. }
  13. public class TerminalExpression : Expression
  14. {
  15. private string data;
  16. public TerminalExpression(string data)
  17. {
  18. this.data = data;
  19. }
  20. public bool Interpret(string context)
  21. {
  22. if (context.Contains(data))
  23. {
  24. return true;
  25. }
  26. return false;
  27. }
  28. }
  29. public class OrExpression : Expression
  30. {
  31. private Expression expr1 = null;
  32. private Expression expr2 = null;
  33. public OrExpression(Expression expr1, Expression expr2)
  34. {
  35. this.expr1 = expr1;
  36. this.expr2 = expr2;
  37. }
  38. public bool Interpret(String context)
  39. {
  40. return expr1.Interpret(context) || expr2.Interpret(context);
  41. }
  42. }
  43. public class AndExpression : Expression
  44. {
  45. private Expression expr1 = null;
  46. private Expression expr2 = null;
  47. public AndExpression(Expression expr1, Expression expr2)
  48. {
  49. this.expr1 = expr1;
  50. this.expr2 = expr2;
  51. }
  52. public bool Interpret(String context)
  53. {
  54. return expr1.Interpret(context) && expr2.Interpret(context);
  55. }
  56. }
  57. }
复制代码

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

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public class IteratorEx : IEnumerable //<IteratorEx>
  10. {
  11. public string Name;
  12. private List<IteratorEx> list = new List<IteratorEx>();
  13. //public IEnumerator<IteratorEx> GetEnumerator()
  14. //{
  15. // foreach (var l in list)
  16. // {
  17. // yield return l;
  18. // }
  19. //}
  20. public void SetList(List<IteratorEx> data)
  21. {
  22. list = data;
  23. }
  24. IEnumerator IEnumerable.GetEnumerator()
  25. {
  26. foreach (var l in list)
  27. {
  28. yield return l;
  29. }
  30. //return new IteratorExEnum(list.ToArray());
  31. }
  32. }
  33. public class IteratorExEnum : IEnumerator
  34. {
  35. private IteratorEx[] list;
  36. private int position = -1;
  37. public IteratorExEnum(IteratorEx[] data)
  38. {
  39. list = data;
  40. }
  41. public object Current
  42. {
  43. get
  44. {
  45. try
  46. {
  47. return list[position];
  48. }
  49. catch (IndexOutOfRangeException)
  50. {
  51. throw new InvalidOperationException();
  52. }
  53. }
  54. }
  55. public bool MoveNext()
  56. {
  57. position++;
  58. return position < list.Length;
  59. }
  60. public void Reset()
  61. {
  62. position = -1;
  63. }
  64. }
  65. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. //中介类
  9. public class ChatRoom
  10. {
  11. public static void ShowMessage(User user, string msg)
  12. {
  13. Console.WriteLine(new DateTime().ToString()+"["+ user.Name + "] : " + msg);
  14. }
  15. }
  16. public class User
  17. {
  18. public string Name { get; set; }
  19. public User(string name)
  20. {
  21. Name = name;
  22. }
  23. public void SendMessage(String message)
  24. {
  25. ChatRoom.ShowMessage(this, message);
  26. }
  27. }
  28. }
复制代码

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. public class Memento
  9. {
  10. public string State { get; }
  11. public Memento(string state)
  12. {
  13. State = state;
  14. }
  15. }
  16. public class Originator
  17. {
  18. public string State { get; set; }
  19. public Memento SaveStateToMemento()
  20. {
  21. return new Memento(State);
  22. }
  23. public void GetStateFromMemento(Memento Memento)
  24. {
  25. State = Memento.State;
  26. }
  27. }
  28. public class CareTaker
  29. {
  30. private List<Memento> mementoList = new List<Memento>();
  31. public void Add(Memento state)
  32. {
  33. mementoList.Add(state);
  34. }
  35. public Memento Get(int index)
  36. {
  37. return mementoList[index];
  38. }
  39. }
  40. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. //观察者模式
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public class Subject: IObservable<Subject>
  10. {
  11. public int State {get; set;}
  12. public Subject(int state)
  13. {
  14. State = state;
  15. }
  16. private List<IObserver<Subject>> observers = new List<IObserver<Subject>>();
  17. public IDisposable Subscribe(IObserver<Subject> observer)
  18. {
  19. if (!observers.Contains(observer))
  20. observers.Add(observer);
  21. return new Unsubscriber(observers, observer);
  22. }
  23. private class Unsubscriber : IDisposable
  24. {
  25. private List<IObserver<Subject>> _observers;
  26. private IObserver<Subject> _observer;
  27. public Unsubscriber(List<IObserver<Subject>> observers, IObserver<Subject> observer)
  28. {
  29. this._observers = observers;
  30. this._observer = observer;
  31. }
  32. public void Dispose()
  33. {
  34. if (_observer != null && _observers.Contains(_observer))
  35. _observers.Remove(_observer);
  36. }
  37. }
  38. public void TrackLocation(Subject ob)
  39. {
  40. Console.WriteLine("start");
  41. foreach (var observer in observers)
  42. {
  43. if (ob==null)
  44. observer.OnError(new Exception("unknowExeption"));
  45. else
  46. observer.OnNext(ob);
  47. }
  48. }
  49. public void EndTransmission()
  50. {
  51. foreach (var observer in observers.ToArray())
  52. if (observers.Contains(observer))
  53. observer.OnCompleted();
  54. observers.Clear();
  55. }
  56. }
  57. public class BinaryObserver : IObserver<Subject>
  58. {
  59. public void OnCompleted()
  60. {
  61. Console.WriteLine("complete");
  62. }
  63. public void OnError(Exception error)
  64. {
  65. Console.WriteLine(error.Message);
  66. }
  67. public void OnNext(Subject value)
  68. {
  69. Console.WriteLine("Binary String: " + Convert.ToString(value.State, 2));
  70. }
  71. }
  72. public class OctalObserver : IObserver<Subject>
  73. {
  74. public void OnCompleted()
  75. {
  76. Console.WriteLine("complete");
  77. }
  78. public void OnError(Exception error)
  79. {
  80. Console.WriteLine(error.Message);
  81. }
  82. public void OnNext(Subject value)
  83. {
  84. Console.WriteLine("Octal String: " + Convert.ToString(value.State, 8));
  85. }
  86. }
  87. public class HexaObserver : IObserver<Subject>
  88. {
  89. public void OnCompleted()
  90. {
  91. Console.WriteLine("complete");
  92. }
  93. public void OnError(Exception error)
  94. {
  95. Console.WriteLine(error.Message);
  96. }
  97. public void OnNext(Subject value)
  98. {
  99. Console.WriteLine("Hex String: " + Convert.ToString(value.State,16));
  100. }
  101. }
  102. }
复制代码

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. public class Context
  9. {
  10. public State State { get; set; }
  11. public Context()
  12. {
  13. State = null;
  14. }
  15. }
  16. public interface State
  17. {
  18. void DoAction(Context context);
  19. }
  20. public class StartState : State
  21. {
  22. public void DoAction(Context context)
  23. {
  24. Console.WriteLine("Player is in start state");
  25. context.State = this;
  26. }
  27. public override string ToString()
  28. {
  29. return "Start State";
  30. }
  31. }
  32. public class StopState : State
  33. {
  34. public void DoAction(Context context)
  35. {
  36. Console.WriteLine("Player is in stop state");
  37. context.State = this;
  38. }
  39. public override string ToString()
  40. {
  41. return "Stop State";
  42. }
  43. }
  44. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. public abstract class AbstractCustomer
  9. {
  10. public abstract bool IsNull();
  11. public abstract string Name { get; }
  12. }
  13. public class RealCustomer : AbstractCustomer
  14. {
  15. public override string Name { get; }
  16. public RealCustomer(string name)
  17. {
  18. Name = name;
  19. }
  20. public override bool IsNull()
  21. {
  22. return false;
  23. }
  24. }
  25. public class NullCustomer : AbstractCustomer
  26. {
  27. public override string Name { get { return "Not Available in Customer Database"; } }
  28. public override bool IsNull()
  29. {
  30. return true;
  31. }
  32. }
  33. public class CustomerFactory
  34. {
  35. public static string[] names = {"Rob", "Joe", "Julie"};
  36. public static AbstractCustomer getCustomer(string name)
  37. {
  38. if(names.Contains(name))
  39. {
  40. return new RealCustomer(name);
  41. }
  42. return new NullCustomer();
  43. }
  44. }
  45. }
复制代码

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

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace ExercisePrj.Dsignmode
  8. {
  9. public interface IStrategy
  10. {
  11. int DoOperation(int num1, int num2);
  12. }
  13. public class OperationAdd : IStrategy
  14. {
  15. public int DoOperation(int num1, int num2)
  16. {
  17. return num1 + num2;
  18. }
  19. }
  20. public class OperationSubstract : IStrategy
  21. {
  22. public int DoOperation(int num1, int num2)
  23. {
  24. return num1 - num2;
  25. }
  26. }
  27. public class OperationMultiply : IStrategy
  28. {
  29. public int DoOperation(int num1, int num2)
  30. {
  31. return num1 * num2;
  32. }
  33. }
  34. public class ContextEx
  35. {
  36. private IStrategy strategy;
  37. public ContextEx(IStrategy strategy)
  38. {
  39. this.strategy = strategy;
  40. }
  41. public int ExecuteStrategy(int num1, int num2)
  42. {
  43. return strategy.DoOperation(num1, num2);
  44. }
  45. //奇葩的写法简单粗暴
  46. private Dictionary<string, Func<int, int, int>> funcs = new Dictionary<string, Func<int, int, int>>();
  47. public int ExecuteStrategy(string name, int num1, int num2)
  48. {
  49. if(funcs.Count==0)
  50. {
  51. //反射写法
  52. var assembly = Assembly.GetExecutingAssembly();
  53. var types = assembly.GetTypes();
  54. foreach (var t in types)
  55. {
  56. if (t.GetInterface("IStrategy") != null)
  57. {
  58. var instance = assembly.CreateInstance(t.FullName) as IStrategy;
  59. funcs.Add(t.Name, instance.DoOperation);
  60. }
  61. }
  62. //直接添加
  63. //funcs.Add("OperationAdd", new Func<int, int, int>((n1, n2) => { return n1 + n2; }));
  64. //funcs.Add("OperationSubstract", new Func<int, int, int>((n1, n2) => { return n1 - n2; }));
  65. //funcs.Add("OperationMultiply", new Func<int, int, int>((n1, n2) => { return n1 * n2; }));
  66. }
  67. return funcs[name](num1, num2);
  68. }
  69. }
  70. }
复制代码


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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. public abstract class Game
  9. {
  10. public abstract void Initialize();
  11. public abstract void StartPlay();
  12. public abstract void EndPlay();
  13. //模板
  14. public void play()
  15. {
  16. //初始化游戏
  17. Initialize();
  18. //开始游戏
  19. StartPlay();
  20. //结束游戏
  21. EndPlay();
  22. }
  23. }
  24. public class Cricket : Game
  25. {
  26. public override void EndPlay()
  27. {
  28. Console.WriteLine("Cricket Game Finished!");
  29. }
  30. public override void Initialize()
  31. {
  32. Console.WriteLine("Cricket Game Initialized! Start playing.");
  33. }
  34. public override void StartPlay()
  35. {
  36. Console.WriteLine("Cricket Game Started. Enjoy the game!");
  37. }
  38. }
  39. }
复制代码

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

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace ExercisePrj.Dsignmode
  7. {
  8. public interface IComputerPartVisitor
  9. {
  10. void Visit(Computer computer);
  11. void Visit(Mouse mouse);
  12. void Visit(Keyboard keyboard);
  13. void Visit(Monitor monitor);
  14. }
  15. public interface IComputerPart
  16. {
  17. void Accept(IComputerPartVisitor computerPartVisitor);
  18. }
  19. public class Keyboard : IComputerPart
  20. {
  21. public void Accept(IComputerPartVisitor computerPartVisitor)
  22. {
  23. computerPartVisitor.Visit(this);
  24. }
  25. }
  26. public class Monitor : IComputerPart
  27. {
  28. public void Accept(IComputerPartVisitor computerPartVisitor)
  29. {
  30. computerPartVisitor.Visit(this);
  31. }
  32. }
  33. public class Mouse : IComputerPart
  34. {
  35. public void Accept(IComputerPartVisitor computerPartVisitor)
  36. {
  37. computerPartVisitor.Visit(this);
  38. }
  39. }
  40. public class Computer : IComputerPart
  41. {
  42. IComputerPart [] parts;
  43. public Computer()
  44. {
  45. parts = new IComputerPart[] { new Mouse(), new Keyboard(), new Monitor() };
  46. }
  47. public void Accept(IComputerPartVisitor computerPartVisitor)
  48. {
  49. for (int i = 0; i < parts.Length; i++)
  50. {
  51. parts[i].Accept(computerPartVisitor);
  52. }
  53. computerPartVisitor.Visit(this);
  54. }
  55. }
  56. public class ComputerPartDisplayVisitor : IComputerPartVisitor
  57. {
  58. public void Visit(Computer computer)
  59. {
  60. Console.WriteLine("Displaying Computer.");
  61. }
  62. public void Visit(Mouse mouse)
  63. {
  64. Console.WriteLine("Displaying Mouse.");
  65. }
  66. public void Visit(Keyboard keyboard)
  67. {
  68. Console.WriteLine("Displaying Keyboard.");
  69. }
  70. public void Visit(Monitor monitor)
  71. {
  72. Console.WriteLine("Displaying Monitor.");
  73. }
  74. }
  75. }
复制代码

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

您可能感兴趣的文章:

  • c#设计模式 适配器模式详细介绍
  • C#设计模式之外观模式介绍
  • C#中利用代理实现观察者设计模式详解
  • C#设计模式之观察者模式实例讲解
  • C#设计模式之单例模式实例讲解
  • 浅谈c#设计模式之单一原则
  • 浅谈C#设计模式之代理模式
  • 浅谈C#设计模式之工厂模式
  • 举例讲解C#编程中对设计模式中的单例模式的运用
  • 实例解析C#设计模式编程中简单工厂模式的使用


回复

使用道具 举报