您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關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."); } } }
感謝各位的閱讀!關于“C#設計模式之行為型模式的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。