



版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
實(shí)現(xiàn)范例的Observer設(shè)計(jì)模式我們之前己經(jīng)對(duì)委托和事件介紹很多了,現(xiàn)在寫代碼應(yīng)該很容易了,現(xiàn)在在這里直接給出代碼,并在注釋中加以說明。usingSystem;usingSystem.Collections.Generic;usingSystem.Text;namespaceDelegate{//熱水器publicclassHeater{privateinttemperature;publicdelegatevoidBoilHandler(intparam);〃聲明委托publiceventBoilHandlerBoilEvent;〃聲明事件
BoilEvent;〃聲明事件//燒水publicvoidBoilWater(){for(inti=0;i<=100;i++){temperature=i;if(temperature>95){if(BoilEvent!=null){//如果有對(duì)象注冊(cè)BoilEvent(temperature);〃調(diào)用所有注冊(cè)對(duì)象的方法}})))//警報(bào)器publicclassAlarm{publicvoidMakeAlert(intparam){
Console.WriteLine(*Alarm:嘀嘀嘀,水已經(jīng){0}度了:",param);//顯示器publicclassDisplay{publicstaticvoidShowMsg(intparam){〃靜態(tài)方法Console.WriteLine(*Display:水快燒開了,當(dāng)前溫度:{0}度。。param);classProgram{staticvoidMainO{Heaterheater=newHeuterO;Alarmalarm=newAlarm();
heater.BoilEvent+=alarm.MakeAlert;〃注冊(cè)方法heater.BoilEvent+=(newAlarm()).MakeAlert; 〃給匿名對(duì)象注冊(cè)方法heater.BoilEvent+=Display.ShowMsg; 〃注冊(cè)靜態(tài)方法heater.BoilWaterO; 〃燒水,會(huì)自動(dòng)調(diào)用注冊(cè)過對(duì)象的方法})}輸出為:Alarm:嘀嘀嘀,水已經(jīng)96度了:Alarm:嘀嘀嘀,水已經(jīng)96度了:Display:水快燒開了,當(dāng)前溫度:96度。//省略???
.NetFramework中的委托與事件盡管上面的范例很好地完成了我們想要完成的工作,但是我們不僅疑惑:為什么.NetFramework中的事件模型和上面的不同?為什么有很多的EventArgs參數(shù)?在回答上面的問題之前,我們先搞懂.NetFramework的編碼規(guī)范:委托類型的名稱都應(yīng)該以EventHandler結(jié)束。委托的原型定義:有一個(gè)void返回值,并接受兩個(gè)輸入?yún)?shù):一個(gè)Object類型,一個(gè)EvenlArgs類型(或繼承自EventArgs)o事件的命名為委托去掉EventHandler之后剩余的部分。繼承自EventArgs的類型應(yīng)該以EventArgs結(jié)尾。再做一下說明:委托聲明原型中的Object類型的參數(shù)代表了Subject,也就是監(jiān)視對(duì)象,在本例中是Heater(熱水器)?;卣{(diào)函數(shù)(比如Alarm的MakeAlert)可以通過它訪問觸發(fā)事件的對(duì)象(Heater)0EventArgs對(duì)象包含了Observer所感興趣的數(shù)據(jù),在本例中是temperature。上面這些其實(shí)不僅僅是為了編碼規(guī)范而已,這樣也使得程序有更大的靈活性。比如說,如果我們不光想獲得熱水器的溫度,還想在Observer端(警報(bào)器或者顯示器)方法中獲得它的生產(chǎn)日期、型號(hào)、價(jià)格,那么委托和方法的聲明都會(huì)變得很麻煩,而如果我們將熱水器的引用傳給警報(bào)器的方法,就可以在方法中直接訪問熱水器了?,F(xiàn)在我們改寫之前的范例,讓它符合.NetFramework的規(guī)范:usingSystem:usingSystem.Collections.Generic;usingSystem.Text;namespaceDelegate{//熱水器publicclassHeater{privateinttemperature;publicstringtype="RealFireoor;//添加型號(hào)作為演示publicstringarea=*ChinaXian"; //添加產(chǎn)地作為演示〃聲明委托publicdelegatevoidBoiledEventHandler(Objectsender,BoiledEventArgse);publiceventBoiledEventHandlerBoiled;//定義BoiledEventArgs類,傳遞給Observer所感興趣的信息publicclassBoi1edEventAr^s:Fveiit;\i-gs(publicreadonlyinttemperature;publicBoiledEventArgs(inttemperature){this,temperature=temperature;)}//可以供繼承自Heater的類重寫,以便繼承類拒絕其他對(duì)象對(duì)它的監(jiān)視protectedvirtualvoidOnBoiled(BoiledEventArgse){if(Boiled!=null){//如果有對(duì)象注冊(cè)Boiled(this,e);〃調(diào)用所有注冊(cè)對(duì)象的方法
//燒水。publicvoidBoi1Water(){for(inti=0;i<=100;i++){temperature=i;if(temperature>95){〃建立BoiledEventArgs對(duì)象。BoiledEventArgse=newBoiledEventArgs(temperature);OnBoiled(e);//調(diào)用OnBolied方法)))//警報(bào)器
publicclassAlarm(publicvoidMakeAlert(Objectsender,Heater.BoiledEventArgse){Heaterheater=(Heater)sender; 〃這里是不是很熟悉呢?〃訪問sender中的公共字段Console.WriteLine(*Alarm:{0}-{1}:”,heater,area,heater,type);Console.WriteLine(*Alarm:嘀嘀嘀,水已經(jīng){0}度了:",e.temperature);Console.WriteLineO;//顯示器publicclassDisplay{publicstaticvoidShowMsg(Objectsender,Heater.BoiledEventArgse)(〃靜態(tài)方法Heaterheater=(Heater)sender;
Console.WriteLine("Display:{0}-(1}:",heater,area,heater,type);Console.WriteLine(*Display:水快燒開了,當(dāng)前溫度:{0}度。"、e.temperature);Console.WriteLineO;classProgram{staticvoidMain(){Heaterheater=newHeater();Alarmalarm=newAlarm();heater.Boiled+=alarm.MakeAlert;〃注冊(cè)方法heater.Boiled+=(newAlarm()).MakeAlert: 〃給匿名對(duì)象注冊(cè)方法heater.Boiled+=newHeater.BoiledEventHandler(alarm.MakeAlert);
//也可以這么注冊(cè)heater.Boiled+=Display.ShowMsg; 〃注冊(cè)靜態(tài)方法heater.BoilWaterO;〃燒水,會(huì)自動(dòng)調(diào)用注冊(cè)過對(duì)象的方法)輸出為:Alarm:ChinaXian-RealFire001:Alarm:嘀嘀嘀,水已經(jīng)96度了:Alarm:ChinaXian-RealFire001:Alarm:嘀嘀嘀,水已經(jīng)96度了:Alarm:ChinaXian-RealFire001:Alarm:嘀嘀嘀,水已經(jīng)96度了:Display:ChinaXian-RealFire001:
Display:水快燒開了,當(dāng)前溫度:96度?!ㄊ÷???classServer{staticvoidMain(string[]args){constintBufferSize=8192; //緩存大小,8192BytesConsoleKeykey;Console.WriteLine("Serverisrunning...”);IPAddressip=newIPAddress(newbyte[](127,0,0,1));TcpListenerlistener=newTcpListener(ip,8500);listener.Start(); //開始偵Console.WriteLine(*Start
Listening//獲取一個(gè)連接,同步方法,在此處中斷TcpClientremoteClient=listener.AcceptTcpClient();//打印連接到的客戶端信息Console.WriteLine("ClientConnected!{0}<-{1}\remoteClient.Client.LocalEndPoint,remoteClient.Client.RemoteEndPoint);//獲得流NetworkStreamstreamToClient=remoteClient.GetStreamO;do(//寫入buffer中byte[]buffer=new
byte[BufferSize];intbytesRead;try(lock(streamToClient){bytesRead=streamToClient.Read(buffer,0,BufferSize);)if(bytesRead==0)thrownewException("讀取到0字節(jié)”);Console.WriteLine(*Readingdata,{0}bytes…”,bytesRead);//獲得請(qǐng)求的字符串stringmsg=Encoding.Unicode.GetString(buffer,0,bytesRead);Console.WriteLine("Received:
//轉(zhuǎn)換成大寫并發(fā)送msg=msg.ToUpper();buffer=l.ncoding.Unicode.GetBytes(msg);lock(streamToClient){streamToClient.Write(buffer,0,buffer.Length);)Console.WriteLine(*Sent:{0}”,msg);}catch(Exceptionex){Console.WriteLine(ex.Message);break;)}while(true);streamToClient.Dispose();remoteClient.Close();
Console.WriteLine(*\n\n輸入、"Q\"鍵退key=Console.ReadKey(true).Key;}while(key!=ConsoleKey.Q);)}接下來是客戶端:classClient{staticvoidMain(string[]args){Console.WriteLineC^ClientRunningTcpClientclient;ConsoleKeykey;constintBufferSize=8192;try{
client=newTcpClient();client.Connect('localhost”,8500); //與服務(wù)器連接}catch(Exceptionex){Console.WriteLine(ex.Message);return;)//打印連接到的服務(wù)端信息Console.WriteLine(^ServerConnected!{0}->{1}\client.Client.LocalEndPoint,client.Client.RemoteEndPoint);NetworkstreamstreamToServer=client.GetStreamO;Console.WriteLineC*Menu:S-Send,XExit");
do{key=Console.ReadKey(true).Key;if(key==ConsoleKey.S){//獲取輸入的字符串Console.Write(zzInputthemessage:〃);stringmsg=Console.ReadLineO;byte[]buffer=Encoding.Unicode.GetBytes(msg); //獲得緩存try(lock(streamToServer){streamToServer.Write(buffer,0,buffer.Length); //發(fā)往服務(wù)器Console.WriteLine("Sent:{0}*,msg);
intbytesRead;buffer=newbyte[BufferSize];lock(streamToServer){bytesRead=streamToServer.Read(buffer,0,BufferSize);}msg=Encoding.Unicode.GetString(buffer,0,bytesRead);Console.WriteLine(*Received:{0)*,msg);}catch(Exceptionex){
Console.WriteLine(ex.Message);break;
}while(key!=ConsoleKey.X);streamToServer.DisposeO;client.CloseO;Console.WriteLine(*\n\n輸入\"Q\"鍵退出?!?;do(key=Console.ReadKey(true).Key;}while(key!=ConsoleKey.Q);)publicstructMessage{privatereadonlystringuserName;privatereadonlystringcontent;
privatereadonlyDeiteTimepostDate;publicMessage(stringuserName,stringcontent){this.userName=userName;this,content=content;this.postDate=DateTime.Now;)publicMessage(stringcontent):this("System”,content){}publicstringUserName{get{returnuserName;}}publicstringContent(get{returncontent;}publicDateTimePostDate{get{returnpostDate;}}publicoverridestringToStringO{returnString.Format(*{0}[{1}]:\r\n{2}\r\n*,userName,postDate,content);}}publicinterfaceIMessageSender{boolConnect(IPAddressip,intport); //連接到服務(wù)端boolSendMessage(Messagemsg); //發(fā)送用戶void
注銷系統(tǒng)}publicdelegatevoidMessageReceivedEventHandler(stringmsg);publicdelegatevoidClientConnectedEventHandler(IPEndPointendPoint);publicdelegatevoidConnectionLostEventHandler(stringinfo);publicinterfaceIMessageReceiver(eventMessageReceivedEventHand1erMessageReceived;//接收到發(fā)來的消息eventConnectionLostEventHandlerClientLost; //遠(yuǎn)程主動(dòng)斷開連接eventClientConnectedEventHandlerClientConnected;//遠(yuǎn)程連接到了本地voidStartListen();//voidStartListen();//開始偵聽端voidStopListenO;voidStopListenO;//停止偵聽端publicclassTalker{privateIMessageReceiverreceiver;privateTMessageSendersender;publicTalker(IMessageReceiverreceiver,TMessageSendersender){this.receiver=receiver;this.sender=sender;})publicclass idrr:I'TcpClientclient;StreamstreamToServer;//連接至遠(yuǎn)程publicboolConnect(IPAddressip,intport){try(client=newTcpClient();client.Connect(ip,port);streamToServer=client.GetStreamO; //獲取連接至遠(yuǎn)程的流returntrue;}catch{returnfalse;//發(fā)送消息publicboolSendMessage(Messagemsg){try{lock(streamToServer){byte[]buffer=
Encoding.Unicode.GetBytes(msg.ToStringO);streamToServer.Write(buffer,0,buffer.Length);returntrue;)}catch{returnfalse;//注銷publicvoidSignOut(){if(streamToServer!=null)streamToServer.Dispose();if(client!=null)client.Close();
publicdelegatevoidPortNumberReadyEventHandler(intportNumber);publicclassM(*ss;im?Recciver:IMessageReceivei-(publiceventMessugeReceivedEvcntlkindlerMessageReceived;publiceventConnectionLostEventHandlerClientLost;publiceventC1ientConnectedl:ventHand1erClientConnected;//當(dāng)端口號(hào)Ok的時(shí)候調(diào)用--需要告訴用戶界面使用了哪個(gè)端口號(hào)在偵聽//這里是業(yè)務(wù)上體現(xiàn)不出來,在實(shí)現(xiàn)中才能體現(xiàn)出來的publiceventPortXiimbcrRecidyEventlkindlerPortNumberReady;
privateThreadworkerThread;privateTcpListenerlistener;publicMessageReceiver(){((IMessageReceiver)this).StartListen();)//開始偵聽:顯示實(shí)現(xiàn)接口voidIMessageReceiver.StartListen(){ThreadStartstart=newThreadStart(ListenThreadMethod);workerThread=newThread(start);workerThread.IsBackground=true;workerThread.Start();//線程入口方法
privatevoidListenThreadMethod(){TPAddresslocalIp=IPAddress.ParseC127.0.0.D;listener二newTcpListener(localIp,0);listener.Start();//獲取端口號(hào)IPEndPointendPoint=listener.LocalEndpointasIPEndPoint;intportNumber=endPoint.Port;if(PortNumberReady!=null){PortNumberReady(portNumber);//端口號(hào)已經(jīng)OK,通知用戶界面}while(true){TcpClientremoteClient;try(remoteClient
listener.AcceptTcpClient();}catch{break;)if(ClientConnected!=null){//連接至本機(jī)的遠(yuǎn)程端口endPoint=remoteClient.Client.RemoteEndPointasIPEndPoint;ClientConnected(endPoint);//通知用戶界面遠(yuǎn)程客戶連接}StreamstreamToClient=remoteClient.GetStreamO;byte[]buffer=newbyte[8192];while(true){try(
intbytesRead=streamToClient.Read(buffer,0,8192);if(bytesRead==0){thrownewException,客戶端已斷開連接”);)stringmsg=l-ncoding.Unicode.GetString(buffer,0,bytesRead);if(MessageReceived!=null){MessageReceived(msg);//已經(jīng)收到消息)}catch(Exceptionex){if(ClientLost!=null){ClientLost(ex.Message); 〃客戶連接丟失
break;//退出循環(huán)//停止偵聽端口publicvoidStopListenO{try(listener.StopO;listener=null;workerThread.Abort();}catch{}
publicclassTalker{privateIMessageReceiverreceiver;privateIMessageSendersender;publicTalker(IMessageReceiverreceiver,IMessageSendersender){this.receiver=receiver;this,sender=sender;)publicTalker(){this,receiver=newMessageReceiver();this,sender=newMessageSender();)l)ul)1iceventM
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)村土地流轉(zhuǎn)貸款擔(dān)保合同
- 買塊土地蓋房子的合同5篇
- 舊車置換新車合同協(xié)議2025
- 2025年公園綠化施工分包合同文本
- 杭州市國有建設(shè)用地使用權(quán)出讓合同
- 合同視角:受托人義務(wù)的履行與風(fēng)險(xiǎn)防控
- 2025年工程合同設(shè)計(jì)與委托施工
- 土地開發(fā)合作合同
- 2025年商務(wù)裙樓租賃合同樣本
- 房產(chǎn)變更登記合同模板
- 中華人民共和國文物保護(hù)法
- 小學(xué)五年級(jí)體育教案全冊(cè)(人教版)
- 2024《整治形式主義為基層減負(fù)若干規(guī)定》全文課件
- 20以內(nèi)加減法口算題(10000道)(A4直接打印-每頁100題)
- (完整)消化性潰瘍PPT課件ppt
- 《企業(yè)員工培訓(xùn)國內(nèi)外文獻(xiàn)綜述》4800字
- 華中科技大學(xué)復(fù)變函數(shù)試題(一)
- 三年級(jí)下冊(cè)數(shù)學(xué)教案-速度、時(shí)間和路程 滬教版
- 徽派建筑PPT江西婺源
- 員工試用期延長申請(qǐng)表
- 質(zhì)量管理小組QC活動(dòng)知識(shí)培訓(xùn)講義122頁(PPT 圖表豐富)_ppt
評(píng)論
0/150
提交評(píng)論