定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
abstract class Observer
{
public abstract void Update();
}
abstract class Subject
{
private List observers = new List();
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();
}
}
}
class ConcreteSubject1 : Subject
{
private string subjectState;
public string SubjectState { get => subjectState; set => subjectState = value; }
}
class ConcreteObserver1 : Observer
{
private string name;
private string observerState;
private ConcreteSubject1 subject;
public ConcreteObserver1(ConcreteSubject1 subject, string name)
{
this.Subject = subject;
this.name = name;
}
public override void Update()
{
observerState = Subject.SubjectState;
Console.WriteLine("观察者{0}的新状态是{1}", name, observerState);
}
public ConcreteSubject1 Subject
{
get => subject;
set => subject = value;
}
}
// test
ConcreteSubject1 s = new ConcreteSubject1();
s.Attach(new ConcreteObserver1(s, "X"));
s.Attach(new ConcreteObserver1(s, "Y"));
s.Attach(new ConcreteObserver1(s, "Z"));
s.SubjectState = "ABC";
s.Notify();
// result
观察者X的新状态是ABC
观察者Y的新状态是ABC
观察者Z的新状态是ABC
当一个对象的改变需要同时改变其它对象时,而且不必知道具体有多少对象要改变
解除耦合,让耦合的双方都依赖于抽象,则不是依赖于具体,从而使得各自的变化都不会影响另一边的变化
如果通知者与观察者之间互相不可以认识或无法认识
C#中使用委托来解决缺陷
interface Subject
{
void Notify();
string SubjectState
{
get;
set;
}
}
class StockObserver
{
private string name;
private Subject sub;
public StockObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public void CloseStockMarket()
{
Console.WriteLine("{0} {1}关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
class NBAObserver
{
private string name;
private Subject sub;
public NBAObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public void CloseNBADirectSeeding()
{
Console.WriteLine("{0} {1}关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
delegate void EventHandler(); // 关键点1
class Boss : Subject
{
public event EventHandler Update; // 关键点2
private string action;
public string SubjectState
{
get { return action; }
set { action = value; }
}
public void Notify()
{
Update(); // 关键点3
}
}
// test
Boss boss = new Boss();
StockObserver stock = new StockObserver("股民", boss);
NBAObserver nba = new NBAObserver("球迷", boss);
boss.Update += new EventHandler(stock.CloseStockMarket);
boss.Update += new EventHandler(nba.CloseNBADirectSeeding);
boss.SubjectState = "老板来了!";
boss.Notify();
// result
老板来了! 股民关闭股票行情,继续工作!
老板来了! 球迷关闭NBA直播,继续工作!
委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。
委托方法的使用可以像其他任何方法一样,具有参数和返回值。
委托可以看作是对函数的抽象,是函数的“类“,委托的实例将代表一个具体的函数。
delegate void EventHandler(); // 理解为声明了一个特殊的类
public event EventHandler Update; // 解理为声明了一个类的变量
new EventHandler(stock.CloseStockMarket); // 一个委托的实例
一个委托可以搭载多个方法,所有方法被依次唤起,最重要的是,它可以便得委托对象所搭载的方法并不需要属于同一个类
委托对象所搭载的所有方法必须具有相同的原形和形式,也就是拥有相同的参数列表和返回值类型