设计模式之---观察者模式
观察者模式又称为发布-订阅模式,定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题。这个主题在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。它是依赖倒置原则的体现。
客户端
static void Main(string[] args) { Boss YanXianZe = new Boss(); //看股票的同事 StockObserver Colleage1 = new StockObserver("胡苏杭", YanXianZe); YanXianZe.Attach(Colleage1); YanXianZe.SubjectState = "老板回来了"; //发出通知 YanXianZe.Notify(); Console.Read(); }
通知者接口
interface Subject { void Attach(Observer observer); void Detach(Observer observer); void Notify(); string SubjectState { get; set; } }
具体通知者
//老板 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; } } } //秘书类 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; } } }
抽象观察者
abstract class Observer { protected string name; protected Subject sub; public Observer(string name,Subject subject)//通知者解耦,这是抽象通知者 { this.name = name; this.sub = subject; } 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); } }
观察者模式的特点
观察者模式所做的工作其实就是解除耦合。让耦合的双方都依赖于抽象,而不是依赖与具体,从而使各自的变化都不会影响另一边的变化。
利用委托和事件实现界面通知的解耦
委托时一种引用方法的类型。一旦委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是对函数的抽象,是函数的”类“,委托的实例将代表一个具体的函数。
delegate void EventHandler(); class Boss:Subject { public event EventHandler Update;//注册事件 public void Notify() { Update();//调用事件 } }
class StockObserver { private string name; public StockObserver(string name) { this.name = name; } public void CloseStockMarket() { Console.WriteLine("{0}关闭股票行情,继续工作!",name); } } interface Subject { void Notify(); }
static void Main(string[] args) { Boss yxz = new Boss(); StockObserver colleague = new StockObserver("胡树行"); yxz.Update += new NewFolder1.EventHandler(colleague.CloseStockMarket); //一个委托对象能够搭载多个方法,所有方法会被依次唤起,很重要的是委托对象所搭载的方法可以不属于同一个类。 yxz.Notify(); Console.Read(); }