1,定义
观察者模式(发布-订阅模式(publish-subscribe))
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,这个主题对象在状态发生变化的时候,会通知所有的观察者对象,使他们能够自动更新自己
2,UML图
3,基本代码
namespace 观察者模式
{
class Program
{
static void Main(string[] args)
{
//ConcreteSubject s = new ConcreteSubject();
//s.Attach(new ConcreteObserver(s, "X"));
//s.Attach(new ConcreteObserver(s, "Y"));
//s.Attach(new ConcreteObserver(s, "Z"));
//s.SubjectState = "ABC";
//s.Notify();
//Console.Read();
ConcreteSubject subject = new ConcreteSubject();
subject.Add(new ConcreteObserver(subject, "A"));
subject.Add(new ConcreteObserver(subject, "B"));
subject.Add(new ConcreteObserver(subject, "B"));
subject.SubjectState = "ABC";
subject.Nodify();
Console.Read();
}
}
//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();
// }
// }
//}
////具体通知者
//class ConcreteSubject : Subject
//{
// private string subjectState;
// //具体通知者状态
// public string SubjectState
// {
// get { return subjectState; }
// set { subjectState = value; }
// }
//}
//abstract class Observer
//{
// public abstract void Update();
//}
//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}的新状态是{1}",
// name, observerState);
// }
// //public ConcreteSubject Subject
// //{
// // get { return subject; }
// // set { subject = value; }
// //}
//}
public abstract class Subject
{
private List<Observer> list = new List<Observer>();
public void Add(Observer observer)
{
list.Add(observer);
}
public void Detach(Observer observer)
{
list.Remove(observer);
}
public void Nodify()
{
foreach (var item in list)
{
item.Update();
}
}
}
public class ConcreteSubject : Subject
{
private string subjectState;
public string SubjectState { get => subjectState; set => subjectState = value; }
}
public abstract class Observer
{
public abstract void Update();
}
public class ConcreteObserver : Observer
{
private string name;
private string observerState;
private ConcreteSubject ConcreteSubject;
public ConcreteObserver(ConcreteSubject concreteSubject,string name)
{
this.ConcreteSubject = concreteSubject;
this.name = name;
}
public override void Update()
{
observerState = ConcreteSubject.SubjectState;
Console.WriteLine( "观察者{0}的状态是{1}",name,observerState);
}
}
}
4,简单应用
namespace 观察者模式
{
class Program
{
static void Main(string[] args)
{
//老板胡汉三
Boss huhansan = new Boss();
//看股票的同事
StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);
//看NBA的同事
NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);
huhansan.Attach(tongshi1);
huhansan.Attach(tongshi2);
huhansan.Detach(tongshi1);
//老板回来
huhansan.SubjectState = "我胡汉三回来了!";
//发出通知
huhansan.Notify();
Console.Read();
}
}
//通知者接口
interface Subject
{
void Attach(Observer observer);
void Detach(Observer observer);
void Notify();
string SubjectState
{
get;
set;
}
}
class Secretary : Subject
{
//同事列表
private IList<Observer> observers = new List<Observer>();
private string action;
//增加
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();
}
//前台状态
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
class Boss : Subject
{
//同事列表
private IList<Observer> observers = new List<Observer>();
private string action;
//增加
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();
}
//老板状态
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//抽象观察者
abstract class Observer
{
protected string name;
protected Subject sub;
public Observer(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
public abstract void Update();
}
//看股票的同事
class StockObserver : Observer
{
public StockObserver(string name, Subject sub)
: base(name, sub)
{
}
public override void Update()
{
Console.WriteLine("{0} {1} 关闭股票行情,继续工作!", sub.SubjectState, name);
}
}
//看NBA的同事
class NBAObserver : Observer
{
public NBAObserver(string name, Subject sub)
: base(name, sub)
{
}
public override void Update()
{
Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
}
5,思考
1,什么时候使用
a,放一个对象的改变需要同时改变其他对象的时候,而且不知道有多少对象有待改变
b,当一个抽象模型有两个方面,其中一方面依赖于另一方面,观察者模式能够将这两者封装在独立的对象当中使他们各自独立的改变和复用,可以解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使各自的变化不会影响另一边的变化
6,观察者模式的改进
namespace 观察者模式
{
class Program
{
static void Main(string[] args)
{
//老板胡汉三
Boss huhansan = new Boss();
//看股票的同事
StockObserver tongshi1 = new StockObserver("魏关姹", huhansan);
//看NBA的同事
NBAObserver tongshi2 = new NBAObserver("易管查", huhansan);
huhansan.Update += new EventHandler(tongshi1.CloseStockMarket);
huhansan.Update += new EventHandler(tongshi2.CloseNBADirectSeeding);
//老板回来
huhansan.SubjectState = "我胡汉三回来了!";
//发出通知
huhansan.Notify();
Console.Read();
}
}
//通知者接口
interface Subject
{
void Notify();
string SubjectState
{
get;
set;
}
}
//事件处理程序的委托
delegate void EventHandler();
class Secretary : Subject
{
//声明一事件Update,类型为委托EventHandler
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
class Boss : Subject
{
//声明一事件Update,类型为委托EventHandler
public event EventHandler Update;
private string action;
public void Notify()
{
Update();
}
public string SubjectState
{
get { return action; }
set { action = value; }
}
}
//
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);
}
}
//看NBA的同事
class NBAObserver
{
private string name;
private Subject sub;
public NBAObserver(string name, Subject sub)
{
this.name = name;
this.sub = sub;
}
//关闭NBA直播
public void CloseNBADirectSeeding()
{
Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SubjectState, name);
}
}
}