欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
觀(guān)察者模式(Observer Pattern)

一、 觀(guān)察者(Observer)模式

觀(guān)察者模式又叫做發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-******(Source/Listener)模式或從屬者(Dependents)模式。

觀(guān)察者模式定義了一種一對多的依賴(lài)關(guān)系,讓多個(gè)觀(guān)察者對象同時(shí)監聽(tīng)某一個(gè)主題對象。這個(gè)主題對象在狀態(tài)上發(fā)生變化時(shí),會(huì )通知所有觀(guān)察者對象,使它們能夠自動(dòng)更新自己。

一個(gè)軟件系統常常要求在某一個(gè)對象的狀態(tài)發(fā)生變化的時(shí)候,某些其它的對象做出相應的改變。做到這一點(diǎn)的設計方案有很多,但是為了使系統能夠易于復用,應該選擇低耦合度的設計方案。減少對象之間的耦合有利于系統的復用,但是同時(shí)設計師需要使這些低耦合度的對象之間能夠維持行動(dòng)的協(xié)調一致,保證高度的協(xié)作(Collaboration)。觀(guān)察者模式是滿(mǎn)足這一要求的各種設計方案中最重要的一種。


二、 觀(guān)察者模式的結構

觀(guān)察者模式的類(lèi)圖如下:

 

可以看出,在這個(gè)觀(guān)察者模式的實(shí)現里有下面這些角色:

  • 抽象主題(Subject)角色:主題角色把所有對觀(guān)察考對象的引用保存在一個(gè)聚集里,每個(gè)主題都可以有任何數量的觀(guān)察者。抽象主題提供一個(gè)接口,可以增加和刪除觀(guān)察者對象,主題角色又叫做抽象被觀(guān)察者(Observable)角色,一般用一個(gè)抽象類(lèi)或者一個(gè)接口實(shí)現。
  • 抽象觀(guān)察者(Observer)角色:為所有的具體觀(guān)察者定義一個(gè)接口,在得到主題的通知時(shí)更新自己。這個(gè)接口叫做更新接口。抽象觀(guān)察者角色一般用一個(gè)抽象類(lèi)或者一個(gè)接口實(shí)現。在這個(gè)示意性的實(shí)現中,更新接口只包含一個(gè)方法(即Update()方法),這個(gè)方法叫做更新方法。
  • 具體主題(ConcreteSubject)角色:將有關(guān)狀態(tài)存入具體現察者對象;在具體主題的內部狀態(tài)改變時(shí),給所有登記過(guò)的觀(guān)察者發(fā)出通知。具體主題角色又叫做具體被觀(guān)察者角色(Concrete Observable)。具體主題角色通常用一個(gè)具體子類(lèi)實(shí)現。
  • 具體觀(guān)察者(ConcreteObserver)角色:存儲與主題的狀態(tài)自恰的狀態(tài)。具體現察者角色實(shí)現抽象觀(guān)察者角色所要求的更新接口,以便使本身的狀態(tài)與主題的狀態(tài)相協(xié)調。如果需要,具體現察者角色可以保存一個(gè)指向具體主題對象的引用。具體觀(guān)察者角色通常用一個(gè)具體子類(lèi)實(shí)現。

從具體主題角色指向抽象觀(guān)察者角色的合成關(guān)系,代表具體主題對象可以有任意多個(gè)對抽象觀(guān)察者?韻蟮囊謾V允褂貿橄蠊鄄煺叨皇薔嚀騫鄄煺擼馕蹲胖魈舛韻蟛恍枰酪昧四男〤oncreteObserver類(lèi)型,而只知道抽象Observer類(lèi)型。這就使得具體主題對象可以動(dòng)態(tài)地維護一系列的對觀(guān)察者對象的引用,并在需要的時(shí)候調用每一個(gè)觀(guān)察者共有的Update()方法。這種做法叫做"針對抽象編程"。


三、 觀(guān)察者模式的示意性源代碼

 

// Observer pattern -- Structural example  
using System;
using System.Collections;

// "Subject"
abstract class Subject
{
  
// Fields
  private ArrayList observers = new ArrayList();

  
// Methods
  public void Attach( Observer observer )
  
{
    observers.Add( observer );
  }


  
public void Detach( Observer observer )
  
{
    observers.Remove( observer );
  }


  
public void Notify()
  
{
    
foreach( Observer o in observers )
      o.Update();
  }

}


// "ConcreteSubject"
class ConcreteSubject : Subject
{
  
// Fields
  private string subjectState;

  
// Properties
  public string SubjectState
  
{
    
getreturn subjectState; }
    
set{ subjectState = value; }
  }

}


// "Observer"
abstract class Observer
{
  
// Methods
  abstract public void Update();
}


// "ConcreteObserver"
class ConcreteObserver : Observer
{
  
// Fields
  private string name;
  
private string observerState;
  
private ConcreteSubject subject;

  
// Constructors
  public ConcreteObserver( ConcreteSubject subject,  
    
string name )
  
{
    
this.subject = subject;
    
this.name = name;
  }


  
// Methods
  override public void Update()
  
{
    observerState 
= subject.SubjectState;
    Console.WriteLine( 
"Observer {0}‘s new state is {1}",
      name, observerState );
  }


  
// Properties
  public ConcreteSubject Subject
  
{
    
get return subject; }
    
set { subject = value; }
  }

}


/// <summary>
/// Client test
/// </summary>

public class Client
{
  
public static void Main( string[] args )
  
{
    
// Configure Observer structure
    ConcreteSubject s = new ConcreteSubject();
    s.Attach( 
new ConcreteObserver( s, "1" ) );
    s.Attach( 
new ConcreteObserver( s, "2" ) );
    s.Attach( 
new ConcreteObserver( s, "3" ) );

    
// Change subject and notify observers
    s.SubjectState = "ABC";
    s.Notify();
  }

}

 


四、 C#中的Delegate與Event

實(shí)際上在C#中實(shí)現Observer模式?jīng)]有這么辛苦,.NET中提供了Delegate與Event機制,我們可以利用這種機制簡(jiǎn)化Observer模式。關(guān)于Delegate與Event的使用方法請參考相關(guān)文檔。改進(jìn)后的Observer模式實(shí)現如下:

 

// Observer pattern -- Structural example  
using System;

//Delegate
delegate void UpdateDelegate(); 

//Subject
class Subject
{
  
public event UpdateDelegate UpdateHandler;
  
  
// Methods
  public void Attach( UpdateDelegate ud )
  
{
    UpdateHandler 
+= ud;
  }


  
public void Detach( UpdateDelegate ud )
  
{
    UpdateHandler 
-= ud;
  }

  
  
public void Notify()
  
{
    
if(UpdateHandler != null) UpdateHandler();
  }


}


//ConcreteSubject
class ConcreteSubject : Subject
{
  
// Fields
  private string subjectState;

  
// Properties
  public string SubjectState
  
{
    
getreturn subjectState; }
    
set{ subjectState = value; }
  }

}


// "ConcreteObserver"
class ConcreteObserver
{
  
// Fields
  private string name;
  
private string observerState;
  
private ConcreteSubject subject;

  
// Constructors
  public ConcreteObserver( ConcreteSubject subject,  
    
string name )
  
{
    
this.subject = subject;
    
this.name = name;
  }


  
// Methods
  public void Update()
  
{
    observerState 
= subject.SubjectState;
    Console.WriteLine( 
"Observer {0}‘s new state is {1}",
      name, observerState );
  }


  
// Properties
  public ConcreteSubject Subject
  
{
    
get return subject; }
    
set { subject = value; }
  }

}


// "ConcreteObserver"
class AnotherObserver
{
  
// Methods
  public void Show()
  
{
    Console.WriteLine(
"AnotherObserver got an Notification!");
  }

}


public class Client

  
public static void Main(string[] args)
  

    ConcreteSubject s 
= new ConcreteSubject();
    ConcreteObserver o1 
= new ConcreteObserver(s, "1");
    ConcreteObserver o2 
= new ConcreteObserver(s, "2");
    AnotherObserver o3 
= new AnotherObserver();
    
    s.Attach(
new UpdateDelegate(o1.Update));
    s.Attach(
new UpdateDelegate(o2.Update));
    s.Attach(
new UpdateDelegate(o3.Show));

    s.SubjectState 
= "ABC";
    s.Notify();

    Console.WriteLine(
"--------------------------");
    s.Detach(
new UpdateDelegate(o1.Update));

    s.SubjectState 
= "DEF";
    s.Notify();
  }

}

 

其中,關(guān)鍵的代碼如下:

 

delegate void UpdateDelegate(); 

 

定義一個(gè)Delegate,用來(lái)規范函數結構。不管是ConcreteObserver類(lèi)的Update方法還是AnotherObserver類(lèi)的Show方法都符合該Delegate。這不象用Observer接口來(lái)規范必須使用Update方法那么嚴格。只要符合Delegate所指定的方法結構的方法都可以在后面被事件所處理。

 

public event UpdateDelegate UpdateHandler;

 

定義一個(gè)事件,一旦觸發(fā),可以調用一組符合UpdateDelegate規范的方法。

 

  public void Attach( UpdateDelegate ud )
  
{
    UpdateHandler 
+= ud;
  }

 

訂閱事件。只要是一個(gè)滿(mǎn)足UpdateDelegate的方法,就可以進(jìn)行訂閱操作(如下所示)。

 

    s.Attach(new UpdateDelegate(o1.Update));
    s.Attach(
new UpdateDelegate(o2.Update));
    s.Attach(
new UpdateDelegate(o3.Show));

 

在Notify方法中:

 

  public void Notify()
  
{
    
if(UpdateHandler != null) UpdateHandler();
  }

 

只要UpdateHandler != null(表示有訂閱者),就可以觸發(fā)事件(UpdateHandler()),所有的訂閱者便會(huì )接到通知。


五、 一個(gè)實(shí)際應用觀(guān)察者模式的例子

該例子演示了注冊的投資者在股票市場(chǎng)發(fā)生變化時(shí),可以自動(dòng)得到通知。該例子仍然使用的是傳統的Observer處理手段,至于如何轉換成Delegate與Event留給讀者自己考慮。

 

// Observer pattern -- Real World example  
using System;
using System.Collections;

// "Subject"
abstract class Stock
{
  
// Fields
  protected string symbol;
  
protected double price;
  
private ArrayList investors = new ArrayList();

  
// Constructor
  public Stock( string symbol, double price )
  
{
    
this.symbol = symbol;
    
this.price = price;
  }


  
// Methods
  public void Attach( Investor investor )
  
{
    investors.Add( investor );
  }


  
public void Detach( Investor investor )
  
{
    investors.Remove( investor );
  }


  
public void Notify()
  
{
    
foreach( Investor i in investors )
      i.Update( 
this );
  }


  
// Properties
  public double Price
  
{
    
getreturn price; }
    
set
    
{
      price 
= value;
      Notify(); 
    }

  }


  
public string Symbol
  
{
    
getreturn symbol; }
    
set{ symbol = value; }
  }

}


// "ConcreteSubject"
class IBM : Stock
{
  
// Constructor
  public IBM( string symbol, double price )
    : 
base( symbol, price ) {}
}


// "Observer"
interface IInvestor
{
  
// Methods
  void Update( Stock stock );
}


// "ConcreteObserver"
class Investor : IInvestor
{
  
// Fields
  private string name;
  
private string observerState;
  
private Stock stock;

  
// Constructors
  public Investor( string name )
  
{
    
this.name = name;
  }


  
// Methods
  public void Update( Stock stock )
  
{
    Console.WriteLine( 
"Notified investor {0} of {1}‘s change to {2:C}"
      name, stock.Symbol, stock.Price );
  }


  
// Properties
  public Stock Stock
  
{
    
getreturn stock; }
    
set{ stock = value; }
  }

}


/// <summary>
/// ObserverApp test
/// </summary>

public class ObserverApp
{
  
public static void Main( string[] args )
  
{
    
// Create investors
    Investor s = new Investor( "Sorros" );
    Investor b 
= new Investor( "Berkshire" );

    
// Create IBM stock and attach investors
    IBM ibm = new IBM( "IBM"120.00 );
    ibm.Attach( s );
    ibm.Attach( b );

    
// Change price, which notifies investors
    ibm.Price = 120.10;
    ibm.Price 
= 121.00;
    ibm.Price 
= 120.50;
    ibm.Price 
= 120.75;
  }

}

 


六、 觀(guān)察者模式的優(yōu)缺點(diǎn)

Observer模式的優(yōu)點(diǎn)是實(shí)現了表示層和數據邏輯層的分離,并定義了穩定的更新消息傳遞機制,類(lèi)別清晰,并抽象了更新接口,使得可以有各種各樣不同的表示層(觀(guān)察者)。

但是其缺點(diǎn)是每個(gè)外觀(guān)對象必須繼承這個(gè)抽像出來(lái)的接口類(lèi),這樣就造成了一些不方便,比如有一個(gè)別人寫(xiě)的外觀(guān)對象,并沒(méi)有繼承該抽象類(lèi),或者接口不對,我們又希望不修改該類(lèi)直接使用它。雖然可以再應用Adapter模式來(lái)一定程度上解決這個(gè)問(wèn)題,但是會(huì )造成更加復雜煩瑣的設計,增加出錯幾率。

觀(guān)察者模式的效果有以下幾個(gè)優(yōu)點(diǎn):

(1)觀(guān)察者模式在被觀(guān)察者和觀(guān)察者之間建立一個(gè)抽象的耦合。被觀(guān)察者角色所知道的只是一個(gè)具體現察者聚集,每一個(gè)具體現察者都符合一個(gè)抽象觀(guān)察者的接口。被觀(guān)察者并不認識任何一個(gè)具體觀(guān)察者,它只知道它們都有一個(gè)共同的接口。由于被觀(guān)察者和觀(guān)察者沒(méi)有緊密地耦合在一起,因此它們可以屬于不同的抽象化層次。

(2)觀(guān)察者模式支持廣播通信。被觀(guān)察者會(huì )向所有的登記過(guò)的觀(guān)察者發(fā)出通知。

觀(guān)察者模式有下面的一些缺點(diǎn):

(1)如果一個(gè)被觀(guān)察者對象有很多直接和間接的觀(guān)察者的話(huà),將所有的觀(guān)察者都通知到會(huì )花費很多時(shí)間。

(2)如果在被觀(guān)察者之間有循環(huán)依賴(lài)的話(huà),被觀(guān)察者會(huì )觸發(fā)它們之間進(jìn)行循環(huán)調用,導致系統崩潰。在使用觀(guān)察考模式時(shí)要特別注意這一點(diǎn)。

(3)如果對觀(guān)察者的通知是通過(guò)另外的線(xiàn)程進(jìn)行異步投遞的話(huà),系統必須保證投遞是以自恰的方式進(jìn)行的。

(4)雖然觀(guān)察者模式可以隨時(shí)使觀(guān)察者知道所觀(guān)察的對象發(fā)生了變化,但是觀(guān)察者模式?jīng)]有相應的機制使觀(guān)察者知道所觀(guān)察的對象是怎么發(fā)生變化的。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
觀(guān)察者模式(Observer)解析例子
委托和設計模式(2)(上)
設計模式之觀(guān)察者模式(observer pattern)
觀(guān)察者(Observer)模式
觀(guān)察者模式
行為模式之觀(guān)察者模式
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久