觀察者模式定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同事監(jiān)聽某一個主題對象。這個主題對象在狀態(tài)發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己
class Program
{
static void Main(string[] args)
{
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.Attach(new ConcreteObserver(concreteSubject, "奶茶店"));
concreteSubject.Attach(new ConcreteObserver(concreteSubject, "快餐店"));
concreteSubject.Attach(new ConcreteObserver(concreteSubject, "花店"));
concreteSubject.SubjectState = "顧客來了";
concreteSubject.Notify();//消息通知
Console.ReadLine();
}
}
//抽象消息通知者,一般用一一個抽象類或者一個接口實現(xiàn)。它把所有對觀察者對象的引用保存在一個容器里,每個消息通知者都可以聯(lián)系任何數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象
abstract class Subject
{
private IList<Observer> observers = new List<Observer>();//觀察者列表
//增加觀察者
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();
}
}
}
//抽象觀察者,是所有觀察者的基類,在得到消息發(fā)布者的消息后,使用更新方法更新自己的狀態(tài)
abstract class Observer
{
public abstract void Update();
}
//具體消息通知者,繼承自Subject的具體類,將有關(guān)狀態(tài)存入具體觀察者對象;在具體消息通知者內(nèi)部狀態(tài)改變的時候,給所有在容器中的觀察者發(fā)布消息。
class ConcreteSubject : Subject
{
private string subjectState;//消息通知者的具體消息
//具體被觀察者狀態(tài)
public string SubjectState
{
get { return subjectState; }
set { subjectState = value; }
}
}
//具體觀察者,實現(xiàn)抽象觀察者的接口,以便本身的狀態(tài)與消息通知者的狀態(tài)相協(xié)調(diào)
class ConcreteObserver : Observer
{
private string name;
private string observerState;
private ConcreteSubject subject;
public ConcreteObserver(ConcreteSubject subject, string name)
{
this.subject = subject;
this.name = name;
}
public override void Update()
{
observerState = subject.SubjectState;
Console.WriteLine("{0}的新狀態(tài)是{1}",name,observerState);
}
public ConcreteSubject Subject
{
get { return subject; }
set { subject = value; }
}
}
觀察者模式主要解決的問題:當(dāng)一個對象狀態(tài)發(fā)生改變后給其他的對象通知
觀察者的優(yōu)點:
觀察者和被觀察者是抽象耦合的,讓耦合的雙方都依賴于抽象,而不是依賴于具體,從而使得各自的變化都不會影響另一邊的變化。
觀察者的缺點:
1、如果一個被觀察者對象有很多的直接或間接的觀察者的話,消耗的時間會增加很多。
2、觀察者模式?jīng)]有相應(yīng)的機制讓觀察者知道所觀察的目標(biāo)對象是怎么發(fā)生變化的,而僅僅是知道被觀察者發(fā)生變化,會有很一些不需要改變狀態(tài)的觀察者被迫發(fā)生狀態(tài)改變。
3、如果觀察者與被觀察者之間有循環(huán)依賴,會造成陷入死循環(huán)中,導(dǎo)致系統(tǒng)崩潰。
發(fā)布訂閱模式需要引用到了事件與委托這個兩種類型
委托
事件
訂閱發(fā)布模式,發(fā)布者的消息發(fā)送者不會講消息直接發(fā)送給訂閱者,這意味著發(fā)布者和訂閱者不知道彼此的存在。在發(fā)布者和訂閱者之間存在第三個組件,稱為消息代理或調(diào)度中心和中間件,它維持著發(fā)布者和訂閱者之間的聯(lián)系,過濾所有發(fā)布者傳入的消息并相應(yīng)地發(fā)布它們給訂閱者。
優(yōu)點
1、支持簡單的廣播通信,當(dāng)對象狀態(tài)發(fā)生改變時,會自動通知已經(jīng)訂閱過的對象
2、發(fā)布者與訂閱者耦合性降低,發(fā)布者只管發(fā)布一條消息后,訂閱者只監(jiān)聽發(fā)布者的事件名,只要發(fā)布者的事件名不變,它不管發(fā)布者如何改變
缺點
1、創(chuàng)建訂閱者需要消耗一定時間的內(nèi)存
2、增加維護的難度文章來源:http://www.zghlxwxcb.cn/news/detail-731204.html
區(qū)別與聯(lián)系
聯(lián)系:
訂閱發(fā)布是觀察者模式的一種變種。
區(qū)別:
1、觀察模式中觀察者和被觀察者是松耦合的關(guān)系、發(fā)布-訂閱模式中完全不存在耦合。
2、觀察模式中觀察者與被觀察者相互感知,發(fā)布-訂閱模式中存在中間調(diào)度工廠。文章來源地址http://www.zghlxwxcb.cn/news/detail-731204.html
class Program
{
static void Main(string[] args)
{
Client c1 = new Client();
ObserverA a = new ObserverA("路北", c1);
ObserverB b = new ObserverB("路南", c1);
c1.Update += new Handler(a.Work);
c1.Update += new Handler(b.Work);
c1.SubjectState = "顧客";
c1.Notify();
}
}
interface Subject
{
public void Notify();
string SubjectState
{
get;
set;
}
}
delegate void Handler();//聲明委托
class Client : Subject
{
public event Handler Update;//聲明Handler(事件處理程序)的委托事件Update方法
private string action;
public void Notify()//引發(fā)Update方法
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
class ObserverA
{
private string name;
private Subject subject;
public ObserverA(string name, Subject subject)
{
this.name = name;
this.subject = subject;
}
public void Work()
{
Console.WriteLine("{0}來了,{1}開始工作",subject.SubjectState,name);
}
}
class ObserverB
{
private string name;
private Subject subject;
public ObserverB(string name, Subject subject)
{
this.name = name;
this.subject = subject;
}
public void Work()
{
Console.WriteLine("{0}來了,{1}開始工作", subject.SubjectState, name);
}
}
到了這里,關(guān)于設(shè)計模式之觀察者(發(fā)布訂閱)模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!