C#設(shè)計(jì)模式之行為型模式詳解
這里列舉行為型模式·到此23種就列完了···這里是看著菜鳥教程來(lái)實(shí)現(xiàn)··,他里邊列了25種,其中過(guò)濾器模式和空對(duì)象模式應(yīng)該不屬于所謂的23種模式
責(zé)任鏈模式:為請(qǐng)求創(chuàng)建一個(gè)接收者對(duì)象的鏈,對(duì)請(qǐng)求的發(fā)送者和接收者進(jìn)行解耦,大部分用于web中吧。。
Task中的continuewith和微軟的tpl數(shù)據(jù)流應(yīng)該是類似這種模式的實(shí)現(xiàn)吧
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//責(zé)任鏈模式
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;
//責(zé)任鏈中的下一個(gè)對(duì)象
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):請(qǐng)求以命令的形式執(zhí)行,CAD的的命令應(yīng)該就是以這種方式執(zhí)行的·二次開發(fā)的時(shí)候通過(guò)特性標(biāo)識(shí)和繼承他的接口來(lái)添加命令,非常方便
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);
}
}
//請(qǐng)求類
public class BuyStock : IOrder
{
private Stock abcStock;
public BuyStock(Stock abcStock)
{
this.abcStock = abcStock;
}
public void Execute()
{
abcStock.Buy();
}
}
//繼承接口的實(shí)體
public class SellStock : IOrder
{
private Stock abcStock;
public SellStock(Stock abcStock)
{
this.abcStock = abcStock;
}
public void Execute()
{
abcStock.Sell();
}
}
//命令調(diào)用類
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();
}
}
}
解釋器模式:就是實(shí)現(xiàn)一種表達(dá)式接口,C#的各種表達(dá)式就是這種實(shí)現(xiàn)吧··這玩意跟富文本編輯器一樣是個(gè)大坑吧··,做好了確實(shí)很好使,一不小心就得跪
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自帶接口···,直接實(shí)現(xiàn)就行了··注意又泛型接口和非泛型接口··非泛型接口迭代對(duì)象返回的是object,泛型接口返回的直接就是對(duì)象了,還有通過(guò)yield的簡(jiǎn)化寫法不用額外去實(shí)現(xiàn)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):用一個(gè)中介對(duì)象封裝一些對(duì)象的交互,中介者使對(duì)象不用顯式的互相引用,MVC和mvp 的c和p都是類似這玩意的實(shí)現(xiàn)吧
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):在不破壞封裝的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在對(duì)象之外保存,
大部分支持回退的操作場(chǎng)景下應(yīng)該都是這種模式··之前做的軟件中有畫圖的操作···支持后退,實(shí)現(xiàn)方式非常簡(jiǎn)單粗暴··,直接吧圖層的畫圖對(duì)象克隆一份保存··只支持5還是10步,講道理這么實(shí)現(xiàn)確實(shí)有點(diǎn)那啥了···
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自帶的有接口提供來(lái)實(shí)現(xiàn)觀察者模式···這里照著msdn來(lái)實(shí)現(xiàn)一遍,自帶的接口里邊還實(shí)現(xiàn)了資源的釋放··,之前并發(fā)編程里邊的rx也是這個(gè)模式的具體實(shí)現(xiàn)·
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));
}
}
}
狀態(tài)模式(State Pattern):當(dāng)對(duì)象內(nèi)部狀態(tài)發(fā)生改變時(shí),行為也跟著改變
這個(gè)模式是為了解決類里邊的大量if和swicth語(yǔ)句,講道理例子寫的有點(diǎn)怪···主體是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";
}
}
}
空對(duì)象模式(Null Object Pattern):就是吧對(duì)空值的判斷定義一個(gè)啥也不做的實(shí)體對(duì)象出來(lái)··C#的Nullable就是這個(gè)的實(shí)現(xiàn)···這玩意不在23種設(shè)計(jì)模式里邊···
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):定義一系列算法,封裝成類,可以相互替換,通過(guò)構(gòu)造不同的類,執(zhí)行不同的操作。這樣做方便調(diào)用,添加新的算法也方便,
最后加了自己之前對(duì)這個(gè)模式的奇葩寫法
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);
}
//奇葩的寫法簡(jiǎn)單粗暴
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的泛型就是這個(gè)模式的實(shí)現(xiàn)吧··照著模子寫就行了
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();
//結(jié)束游戲
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!");
}
}
}
訪問(wèn)者模式(Visitor Pattern):在被訪問(wèn)的類里邊加一個(gè)對(duì)外提供接待訪問(wèn)的接口
把數(shù)據(jù)結(jié)構(gòu)和對(duì)應(yīng)的操作分開·添加操作很容易,但是如果結(jié)構(gòu)變化多的化,改起來(lái)就麻煩了··
沒研究沒用過(guò)····
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.");
}
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于C#實(shí)現(xiàn)的HOOK鍵盤鉤子實(shí)例代碼
這篇文章主要介紹了基于C#實(shí)現(xiàn)的HOOK鍵盤鉤子實(shí)例,需要的朋友可以參考下2014-07-07
關(guān)于C#中ajax跨域訪問(wèn)問(wèn)題
最近做項(xiàng)目,需要跨域請(qǐng)求訪問(wèn)數(shù)據(jù)問(wèn)題。下面通過(guò)本文給大家分享C#中ajax跨域訪問(wèn)代碼詳解,需要的朋友可以參考下2017-05-05
C#使用正則表達(dá)式實(shí)現(xiàn)首字母轉(zhuǎn)大寫的方法
這篇文章主要介紹了C#使用正則表達(dá)式實(shí)現(xiàn)首字母轉(zhuǎn)大寫的方法,涉及C#基于正則表達(dá)式操作字符串的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
C#對(duì)list列表進(jìn)行隨機(jī)排序的方法
這篇文章主要介紹了C#對(duì)list列表進(jìn)行隨機(jī)排序的方法,涉及C#操作list列表的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04

