参考《大话设计模式》
业务场景
人物:老板,秘书,看股票的同事A, 看股票的同事B
逻辑:老板到办公室,秘书提醒同事xxxxxxx
>>第一版(双向耦合)
秘书类:
public class Secretary { private IList<StockObserver> _Observers = new List<StockObserver>(); private string _Action; //添加需要秘书通知的对象 public void Attach(StockObserver observer) { observers.Add(observer); } //秘书发出通知 public void Notify() { foreach(var ob in _Observers) { ob.Update(); } } //秘书的通知内容 public string SecretaryAction { get{return _Action;} set{_Action = value;} } }
看股票的同事类:
public class StockObserver { private string _Name; private Secretary _Sub; public StockObserver(string name, Secretary sub) { _Name = name; _Sub = sub; } public void Update() { Console.WriteLine("{0} {1}关闭股票行情,继续工作", sub.SecretaryAction, _Name); } }
客户端:
static void Main(string[] args) { Secretary sec = new Secretary(); StockObserver sto1 = new StockObserver("同事A", sec); StockObserver sto2 = new StockObserver("同事B", sec); //秘书登记下两位要被通知的同事 sec.Attach(sto1); sec.Attach(sto2); sec.SecretaryAction = "老板来了"; sec.Notify(); }
缺点:
1. 秘书类和看股票同事类相关耦合在一起, 秘书类需要增加看股票者, 看股票者需要访问秘书类的信息。
2. 如果要添加看NBA同事类, 秘书类也要跟着修改,不符合开闭原则。
> >解耦版1
抽象观察者:
public abstract class Observer { private string _Name; private Secretary _Sub; public Observer(string name, Secretary sub) { _Name = name; _Sub = sub; } public abstract void Update(); }
具体观察者-看股票的同事:
public class StockObserver : Observer { public StockObserver(string name, Secretary sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0} {1} 关闭股票行情, 继续工作!", sub.SecretaryAction, name); } }
具体观察者-看NBA的同事:
public NBAObserver : Observer { public NBAObserver(string name, Secretary sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0} {1} 关闭NBA直播,继续工作!", sub.SecretaryAction, name); } }
秘书类:
public class Secretary { private IList<Observer> _Observers = new List<Observer>(); private string _Action; public string SecretaryAction { get{return _Action;} set{_Action = value;} } //add observer public void Attach(Observer observer) { _Observers.Add(observer); } //remove observer public void Remove(Observer observer) { _Observer.Remove(observer); } public void Notify() { foreach(var ob in obs) { ob.Update(); } observers.foreach(obs => obs.update()); } }
缺点: 通过观察者抽象类完成了秘书类中对观察者类地解耦,但在具体观察者类中仍和秘书类存在耦合(观察者不应依赖具体的通知者)。
> > 解耦版二
通知者抽象类:
public abstract class Subject { public abstract void Attach(Observer observer); public abstract void Remove(Observer observer); public abstract void Notify(); public string SubjectAction{ get; set; } }
秘书类:
public class Secretary : Subject { private IList<Observer> _Observers = new List<Observer>(); public override void Attach(Observer observer) { _Observers .Add(observer); } public override void Remove(Observer observer) { _Observers .Remove(observer); } public override void Notify() { foreach(var ob in _Observers) { ob.Update(); } } }
观察者—看股票者:
public class StockObserver : Observer { public StockObserver(string name, Subject sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0} {1} 关闭股票行情, 继续工作!", _Sub.SubjectAction, _Name); } }
观察者—看NBA者:
public class NBAObserver : Observer { public NBAObserver(string name, Subject sub) : base(name, sub) { } public override void Update() { Console.WriteLine("{0} {1} 关闭NBA, 继续工作!", _Sub.SubjectAction, _Name); } }
客户端:
Secretary sec = new Secretary(); StockObserver sto = new StockObserver("Tom", sec); NBAObserver no = new NBAObserver("Jack", sec); sec.Attach(sto); sec.Attach(no ); sec.SubjectAction = "Boss is coming"; sec.Notify();
类图:
