C#设计模式之行为型模式详解
这里列举行为型模式·到此23种就列完了···这里是看着菜鸟教程来实现··,他里边列了25种,其中过滤器模式和空对象模式应该不属于所谓的23种模式
责任链模式:为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦,大部分用于web中吧。。
Task中的continuewith和微软的tpl数据流应该是类似这种模式的实现吧
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
//责任链模式
namespaceExercisePrj.Dsignmode
{
publicabstractclassAbstractLogger
{
publicstaticintINFO=1;
publicstaticintDEBUG=2;
publicstaticintERROR=3;
protectedintlevel;
//责任链中的下一个对象
protectedAbstractLoggernextLogger;
publicvoidSetNextLogger(AbstractLoggernext)
{
nextLogger=next;
}
publicvoidLogMessage(intlevel,stringmessage)
{
if(this.level<=level)
{
Write(message);
}
if(nextLogger!=null)
{
nextLogger.LogMessage(level,message);
}
}
protectedabstractvoidWrite(stringmessage);
}
publicclassConsoleLogger:AbstractLogger
{
publicConsoleLogger(intlevel)
{
this.level=level;
}
protectedoverridevoidWrite(stringmessage)
{
Console.WriteLine("StandardConsole::Logger:"+message);
}
}
publicclassErrorLogger:AbstractLogger
{
publicErrorLogger(intlevel)
{
this.level=level;
}
protectedoverridevoidWrite(Stringmessage)
{
Console.WriteLine("ErrorConsole::Logger:"+message);
}
}
publicclassFileLogger:AbstractLogger
{
publicFileLogger(intlevel)
{
this.level=level;
}
protectedoverridevoidWrite(Stringmessage)
{
Console.WriteLine("File::Logger:"+message);
}
}
}
命令模式(CommandPattern):请求以命令的形式执行,CAD的的命令应该就是以这种方式执行的·二次开发的时候通过特性标识和继承他的接口来添加命令,非常方便
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
//命令模式
namespaceExercisePrj.Dsignmode
{
publicinterfaceIOrder
{
voidExecute();
}
publicclassStock
{
privatestringname="ABC";
privateintquantity=10;
publicvoidBuy()
{
Console.WriteLine("Stockname:{0},quantity:{1},bought",name,quantity);
}
publicvoidSell()
{
Console.WriteLine("Stockname:{0},quantity:{1}sold",name,quantity);
}
}
//请求类
publicclassBuyStock:IOrder
{
privateStockabcStock;
publicBuyStock(StockabcStock)
{
this.abcStock=abcStock;
}
publicvoidExecute()
{
abcStock.Buy();
}
}
//继承接口的实体
publicclassSellStock:IOrder
{
privateStockabcStock;
publicSellStock(StockabcStock)
{
this.abcStock=abcStock;
}
publicvoidExecute()
{
abcStock.Sell();
}
}
//命令调用类
publicclassBroker
{
privateListorderList=newList();
publicvoidtakeOrder(IOrderorder)
{
orderList.Add(order);
}
publicvoidplaceOrders()
{
foreach(IOrderorderinorderList)
{
order.Execute();
}
orderList.Clear();
}
}
}
解释器模式:就是实现一种表达式接口,C#的各种表达式就是这种实现吧··这玩意跟富文本编辑器一样是个大坑吧··,做好了确实很好使,一不小心就得跪
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
//解释器模式
namespaceExercisePrj.Dsignmode
{
publicinterfaceExpression
{
boolInterpret(stringcontext);
}
publicclassTerminalExpression:Expression
{
privatestringdata;
publicTerminalExpression(stringdata)
{
this.data=data;
}
publicboolInterpret(stringcontext)
{
if(context.Contains(data))
{
returntrue;
}
returnfalse;
}
}
publicclassOrExpression:Expression
{
privateExpressionexpr1=null;
privateExpressionexpr2=null;
publicOrExpression(Expressionexpr1,Expressionexpr2)
{
this.expr1=expr1;
this.expr2=expr2;
}
publicboolInterpret(Stringcontext)
{
returnexpr1.Interpret(context)||expr2.Interpret(context);
}
}
publicclassAndExpression:Expression
{
privateExpressionexpr1=null;
privateExpressionexpr2=null;
publicAndExpression(Expressionexpr1,Expressionexpr2)
{
this.expr1=expr1;
this.expr2=expr2;
}
publicboolInterpret(Stringcontext)
{
returnexpr1.Interpret(context)&&expr2.Interpret(context);
}
}
}
迭代器模式(IteratorPattern):.NET自带接口···,直接实现就行了··注意又泛型接口和非泛型接口··非泛型接口迭代对象返回的是object,泛型接口返回的直接就是对象了,还有通过yield的简化写法不用额外去实现IEnumerator接口
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicclassIteratorEx:IEnumerable//
{
publicstringName;
privateListlist=newList();
//publicIEnumeratorGetEnumerator()
//{
//foreach(varlinlist)
//{
//yieldreturnl;
//}
//}
publicvoidSetList(Listdata)
{
list=data;
}
IEnumeratorIEnumerable.GetEnumerator()
{
foreach(varlinlist)
{
yieldreturnl;
}
//returnnewIteratorExEnum(list.ToArray());
}
}
publicclassIteratorExEnum:IEnumerator
{
privateIteratorEx[]list;
privateintposition=-1;
publicIteratorExEnum(IteratorEx[]data)
{
list=data;
}
publicobjectCurrent
{
get
{
try
{
returnlist[position];
}
catch(IndexOutOfRangeException)
{
thrownewInvalidOperationException();
}
}
}
publicboolMoveNext()
{
position++;
returnposition
中介者模式(MediatorPattern):用一个中介对象封装一些对象的交互,中介者使对象不用显式的互相引用,MVC和mvp的c和p都是类似这玩意的实现吧
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
//中介类
publicclassChatRoom
{
publicstaticvoidShowMessage(Useruser,stringmsg)
{
Console.WriteLine(newDateTime().ToString()+"["+user.Name+"]:"+msg);
}
}
publicclassUser
{
publicstringName{get;set;}
publicUser(stringname)
{
Name=name;
}
publicvoidSendMessage(Stringmessage)
{
ChatRoom.ShowMessage(this,message);
}
}
}
备忘录模式(MementoPattern):在不破坏封装的前提下,捕获一个对象的内部状态,并在对象之外保存,
大部分支持回退的操作场景下应该都是这种模式··之前做的软件中有画图的操作···支持后退,实现方式非常简单粗暴··,直接吧图层的画图对象克隆一份保存··只支持5还是10步,讲道理这么实现确实有点那啥了···
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicclassMemento
{
publicstringState{get;}
publicMemento(stringstate)
{
State=state;
}
}
publicclassOriginator
{
publicstringState{get;set;}
publicMementoSaveStateToMemento()
{
returnnewMemento(State);
}
publicvoidGetStateFromMemento(MementoMemento)
{
State=Memento.State;
}
}
publicclassCareTaker
{
privateListmementoList=newList();
publicvoidAdd(Mementostate)
{
mementoList.Add(state);
}
publicMementoGet(intindex)
{
returnmementoList[index];
}
}
}
观察者模式(ObserverPattern):.net自带的有接口提供来实现观察者模式···这里照着msdn来实现一遍,自带的接口里边还实现了资源的释放··,之前并发编程里边的rx也是这个模式的具体实现·
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
//观察者模式
namespaceExercisePrj.Dsignmode
{
publicclassSubject:IObservable
{
publicintState{get;set;}
publicSubject(intstate)
{
State=state;
}
privateList>observers=newList>();
publicIDisposableSubscribe(IObserverobserver)
{
if(!observers.Contains(observer))
observers.Add(observer);
returnnewUnsubscriber(observers,observer);
}
privateclassUnsubscriber:IDisposable
{
privateList>_observers;
privateIObserver_observer;
publicUnsubscriber(List>observers,IObserverobserver)
{
this._observers=observers;
this._observer=observer;
}
publicvoidDispose()
{
if(_observer!=null&&_observers.Contains(_observer))
_observers.Remove(_observer);
}
}
publicvoidTrackLocation(Subjectob)
{
Console.WriteLine("start");
foreach(varobserverinobservers)
{
if(ob==null)
observer.OnError(newException("unknowExeption"));
else
observer.OnNext(ob);
}
}
publicvoidEndTransmission()
{
foreach(varobserverinobservers.ToArray())
if(observers.Contains(observer))
observer.OnCompleted();
observers.Clear();
}
}
publicclassBinaryObserver:IObserver
{
publicvoidOnCompleted()
{
Console.WriteLine("complete");
}
publicvoidOnError(Exceptionerror)
{
Console.WriteLine(error.Message);
}
publicvoidOnNext(Subjectvalue)
{
Console.WriteLine("BinaryString:"+Convert.ToString(value.State,2));
}
}
publicclassOctalObserver:IObserver
{
publicvoidOnCompleted()
{
Console.WriteLine("complete");
}
publicvoidOnError(Exceptionerror)
{
Console.WriteLine(error.Message);
}
publicvoidOnNext(Subjectvalue)
{
Console.WriteLine("OctalString:"+Convert.ToString(value.State,8));
}
}
publicclassHexaObserver:IObserver
{
publicvoidOnCompleted()
{
Console.WriteLine("complete");
}
publicvoidOnError(Exceptionerror)
{
Console.WriteLine(error.Message);
}
publicvoidOnNext(Subjectvalue)
{
Console.WriteLine("HexString:"+Convert.ToString(value.State,16));
}
}
}
状态模式(StatePattern):当对象内部状态发生改变时,行为也跟着改变
这个模式是为了解决类里边的大量if和swicth语句,讲道理例子写的有点怪···主体是context
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicclassContext
{
publicStateState{get;set;}
publicContext()
{
State=null;
}
}
publicinterfaceState
{
voidDoAction(Contextcontext);
}
publicclassStartState:State
{
publicvoidDoAction(Contextcontext)
{
Console.WriteLine("Playerisinstartstate");
context.State=this;
}
publicoverridestringToString()
{
return"StartState";
}
}
publicclassStopState:State
{
publicvoidDoAction(Contextcontext)
{
Console.WriteLine("Playerisinstopstate");
context.State=this;
}
publicoverridestringToString()
{
return"StopState";
}
}
}
空对象模式(NullObjectPattern):就是吧对空值的判断定义一个啥也不做的实体对象出来··C#的Nullable就是这个的实现···这玩意不在23种设计模式里边···
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicabstractclassAbstractCustomer
{
publicabstractboolIsNull();
publicabstractstringName{get;}
}
publicclassRealCustomer:AbstractCustomer
{
publicoverridestringName{get;}
publicRealCustomer(stringname)
{
Name=name;
}
publicoverrideboolIsNull()
{
returnfalse;
}
}
publicclassNullCustomer:AbstractCustomer
{
publicoverridestringName{get{return"NotAvailableinCustomerDatabase";}}
publicoverrideboolIsNull()
{
returntrue;
}
}
publicclassCustomerFactory
{
publicstaticstring[]names={"Rob","Joe","Julie"};
publicstaticAbstractCustomergetCustomer(stringname)
{
if(names.Contains(name))
{
returnnewRealCustomer(name);
}
returnnewNullCustomer();
}
}
}
策略模式(StrategyPattern):定义一系列算法,封装成类,可以相互替换,通过构造不同的类,执行不同的操作。这样做方便调用,添加新的算法也方便,
最后加了自己之前对这个模式的奇葩写法
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Reflection;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicinterfaceIStrategy
{
intDoOperation(intnum1,intnum2);
}
publicclassOperationAdd:IStrategy
{
publicintDoOperation(intnum1,intnum2)
{
returnnum1+num2;
}
}
publicclassOperationSubstract:IStrategy
{
publicintDoOperation(intnum1,intnum2)
{
returnnum1-num2;
}
}
publicclassOperationMultiply:IStrategy
{
publicintDoOperation(intnum1,intnum2)
{
returnnum1*num2;
}
}
publicclassContextEx
{
privateIStrategystrategy;
publicContextEx(IStrategystrategy)
{
this.strategy=strategy;
}
publicintExecuteStrategy(intnum1,intnum2)
{
returnstrategy.DoOperation(num1,num2);
}
//奇葩的写法简单粗暴
privateDictionary>funcs=newDictionary>();
publicintExecuteStrategy(stringname,intnum1,intnum2)
{
if(funcs.Count==0)
{
//反射写法
varassembly=Assembly.GetExecutingAssembly();
vartypes=assembly.GetTypes();
foreach(vartintypes)
{
if(t.GetInterface("IStrategy")!=null)
{
varinstance=assembly.CreateInstance(t.FullName)asIStrategy;
funcs.Add(t.Name,instance.DoOperation);
}
}
//直接添加
//funcs.Add("OperationAdd",newFunc((n1,n2)=>{returnn1+n2;}));
//funcs.Add("OperationSubstract",newFunc((n1,n2)=>{returnn1-n2;}));
//funcs.Add("OperationMultiply",newFunc((n1,n2)=>{returnn1*n2;}));
}
returnfuncs[name](num1,num2);
}
}
}
模板模式(TemplatePattern):.net的泛型就是这个模式的实现吧··照着模子写就行了
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicabstractclassGame
{
publicabstractvoidInitialize();
publicabstractvoidStartPlay();
publicabstractvoidEndPlay();
//模板
publicvoidplay()
{
//初始化游戏
Initialize();
//开始游戏
StartPlay();
//结束游戏
EndPlay();
}
}
publicclassCricket:Game
{
publicoverridevoidEndPlay()
{
Console.WriteLine("CricketGameFinished!");
}
publicoverridevoidInitialize()
{
Console.WriteLine("CricketGameInitialized!Startplaying.");
}
publicoverridevoidStartPlay()
{
Console.WriteLine("CricketGameStarted.Enjoythegame!");
}
}
}
访问者模式(VisitorPattern):在被访问的类里边加一个对外提供接待访问的接口
把数据结构和对应的操作分开·添加操作很容易,但是如果结构变化多的化,改起来就麻烦了··
没研究没用过····
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceExercisePrj.Dsignmode
{
publicinterfaceIComputerPartVisitor
{
voidVisit(Computercomputer);
voidVisit(Mousemouse);
voidVisit(Keyboardkeyboard);
voidVisit(Monitormonitor);
}
publicinterfaceIComputerPart
{
voidAccept(IComputerPartVisitorcomputerPartVisitor);
}
publicclassKeyboard:IComputerPart
{
publicvoidAccept(IComputerPartVisitorcomputerPartVisitor)
{
computerPartVisitor.Visit(this);
}
}
publicclassMonitor:IComputerPart
{
publicvoidAccept(IComputerPartVisitorcomputerPartVisitor)
{
computerPartVisitor.Visit(this);
}
}
publicclassMouse:IComputerPart
{
publicvoidAccept(IComputerPartVisitorcomputerPartVisitor)
{
computerPartVisitor.Visit(this);
}
}
publicclassComputer:IComputerPart
{
IComputerPart[]parts;
publicComputer()
{
parts=newIComputerPart[]{newMouse(),newKeyboard(),newMonitor()};
}
publicvoidAccept(IComputerPartVisitorcomputerPartVisitor)
{
for(inti=0;i
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。