观察者模式
	
	观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者。当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式。
	
	 观察者结构图: 
	 
	
	使用场景:老板回来通知员工需要进入工作状态。
	定义观察者的抽象类:
复制代码 代码如下:
	
	abstract class Observer
	{
	protected string name;
	protected ISubject sub;
	public Observer(string name, ISubject sub)
	{
	this.name = name;
	this.sub = sub;
	}
	public abstract void Update();
	}
	
	看NBA直播的同事:
复制代码 代码如下:
	
	//使用OO
	class NBAObserver : Observer
	{
	public NBAObserver(string name, ISubject sub)
	: base(name, sub)
	{ }
	public override void Update()
	{
	//throw new NotImplementedException();
	Console.WriteLine("{0} {1}关闭NBA直播,继续工作!",sub.SubjectState,name);
	}
	}
	//使用事件和委托
	class NBAObserver2
	{
	private string name;
	private ISubject2 sub;
	public NBAObserver2(string name, ISubject2 sub)
	{
	this.name = name;
	this.sub = sub;
	}
	public void CloseStockMarket()
	{
	Console.WriteLine("{0} {1}关闭NBA直播,继续工作!", sub.SubjectState, name);
	}
	}
	
	看股票的同事:
复制代码 代码如下:
	
	//使用OO
	class StockObserver : Observer
	{
	public StockObserver(string name, ISubject sub) : base(name,sub)
	{ }
	public override void Update()
	{
	//throw new NotImplementedException();
	Console.WriteLine("{0} {1}关闭股票行情,继续工作!",sub.SubjectState,name);
	}
	}
	//使用事件和委托
	class StockObserver2
	{
	private string name;
	private ISubject2 sub;
	public StockObserver2(string name, ISubject2 sub)
	{
	this.name = name;
	this.sub = sub;
	}
	public void CloseNBA()
	{
	Console.WriteLine("{0} {1}关闭股票行情,继续工作!", sub.SubjectState, name);
	}
	}
	
	上的身份是订阅者,下面定义发布者:
复制代码 代码如下:
	
	//使用OO
	interface ISubject
	{
	void Attach(Observer observer);
	void Detach(Observer observer);
	void Notify();
	string SubjectState
	{
	get;
	set;
	}
	}
	class Boss : ISubject
	{
	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; }
	}
	}
	//使用事件和委托
	interface ISubject2
	{
	void Notify();
	string SubjectState
	{
	get;
	set;
	}
	}
	delegate void EventHandler();
	class Boss2 : ISubject2
	{
	public event EventHandler Update;
	private string action;
	public void Notify()
	{
	Update();
	}
	public string SubjectState
	{
	get { return action; }
	set { action = value; }
	}
	}
	
	主函数调用:
复制代码 代码如下:
	
	class Program
	{
	static void Main(string[] args)
	{
	//观察者模式OO实现
	Boss huhansan = new Boss();
	StockObserver tongshi1 = new StockObserver("name1",huhansan);
	NBAObserver tonshi2 = new NBAObserver("name2", huhansan);
	huhansan.Attach(tongshi1);
	huhansan.Attach(tonshi2);
	huhansan.SubjectState = "我1回来了";
	huhansan.Notify();
	//观察者模式c#事件实现
	Boss2 huhansan2 = new Boss2();
	StockObserver2 tongshi3 = new StockObserver2("name3", huhansan2);
	NBAObserver2 tonshi4 = new NBAObserver2("name4", huhansan2);
	huhansan2.Update += new EventHandler(tongshi3.CloseNBA);
	huhansan2.Update += new EventHandler(tonshi4.CloseStockMarket);
	huhansan2.SubjectState = "我2回来了";
	huhansan2.Notify();
	Console.ReadKey();
	}
	}
	
	委托就是一种引用方法的类型,一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做是对函数的抽象,是函数的一个类,委托实例代表一个具体的函数,而且一个委托可以搭载多个方法,所有方法被依次唤醒。
	
	 1 观察者模式 
	一个简单的例子,比如说猫叫,老鼠跑,主人被惊醒。
	在不知道观察者模式之前,我们的代码可能是这样的。
复制代码 代码如下:
	
	//老鼠类  
	class Mouse   
	{  
	     public void Run()   
	     {  
	         Console.WriteLine("老鼠跑了!");  
	     }  
	}  
	//主人类  
	class Master   
	{  
	     public void Wake()  
	     {  
	         Console.WriteLine("主人醒了!");  
	     }  
	}  
	//猫类  
	class Cat   
	{  
	     public void Cry ()  
	     {  
	         Console.WriteLine("猫叫了!");  
	         new Mouse().Run();//猫叫的同时,调用老鼠跑的方法。  
	         new Master().Wake();//猫叫的同时,调用主人醒的方法。  
	     }  
	}  
	class Program  
	{  
	     static void Main(string[] args)  
	     {  
	         Cat cat = new Cat();  
	         cat.Cry();  
	         Console.ReadLine();  
	     }  
	}  
	
	这个代码基本上能实现所有的功能。但是,这个方法特别不利用扩展,
	试想,如果,猫叫后,狗也叫,那是不是也要在猫叫的方法里重新加入狗叫的方法?
	或者说,猫叫后,主人他老婆也醒了,是不是也要在猫叫的方法里加入他老婆醒的方法呢?
	显然,这样的代码不利用维护,也不是面向对象的代码。
	观察者模式能够很好的解决这个问题。
	观察者模式定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于他的对象都得到通知并自动更新。在我们的例子中,猫和老鼠,主人,狗,主人他老婆是一对多的依赖,当猫叫时,所有依赖于它的对象都会自动执行某个操作。
	观察者模式的实现,一般有下面四部分组成。
	1.ISubject接口(抽象目标),含方法Notify,Register,UnRegister(名字可以自己任意取名)
	2.Subject类(实体目标),实现ISubject接口,一般只有一个
	3.IObservable接口(抽象观察者)。
	4 Observer类(实体观察者),实现IObservable接口,一般有多个。
	观察者模式中的[注册--通知--注销]图示:
	1. 观察者(Observer)将自己(Regiester)注册到被观察对象(Subject)中,被观察对象将观察者放在一个容器(Container)。Container一般为Ilist,Arraylist等数据结构,存放多个IObservable接口变量。
	2.当被观察对象(Subject)发生变化(如图中的AskPriceChanged)时,容器(Container)中的所有观察者(Observer)都得到通知(Notify 方法),此时观察者会自动执行某些方法。
	3.当观察者不想继续观察被观察者时,可以注销(UnRegiester方法)
	上面的例子中改造后变成:
	1.ISubject接口:
复制代码 代码如下:
	
	interface ISubject  
	    {  
	        void Notify();//主题变动时,通知虽有观察者  
	        void Regiester(IObservable o);//观察者注册  
	        void UnRegiester(IObservable o);//观察者取消注册,此时主题发生任何变动,观察者都不会得到通知。  
	    }
	
	2.Subject 类:
复制代码 代码如下:
	
	class Cat : ISubject  
	   {  
	       private IList<IObservable> observers = new List<IObservable>();  
	       public void Notify()  
	       {  
	           foreach (IObservable o in observers) //逐个通知观察者  
	           {  
	               o.Action();  
	           }  
	       }  
	       public void Regiester(IObservable o)  
	       {  
	           if (o != null || !observers.Contains(o))  
	           {  
	               observers.Add(o);  
	           }  
	       }  
	       public void UnRegiester(IObservable o)  
	       {  
	           if (observers != null && observers.Contains(o))  
	           {  
	               observers.Remove(o);  
	           }  
	       }  
	       public void Cry()  
	       {  
	           Console.WriteLine("猫叫了!");  
	           Notify();  
	       }  
	   }
	
	3. IObservable 接口:
复制代码 代码如下:
	
	interface IObservable  
	{  
	    void Action();//观察者对主题变动所对应的操作  
	}
	
	4.Observer类(2个,Mouse和Master)
复制代码 代码如下:
	
	class Mouse : IObservable  
	   {  
	       public void Action()  
	       {  
	           Console.WriteLine("鼠跑了!");  
	       }  
	   }  
	   class Master : IObservable  
	   {  
	       public void Action()  
	       {  
	           Console.WriteLine("主人醒了!");  
	       }  
	   }
	
	5.主程序
复制代码 代码如下:
	
	Mouse mouse = new Mouse();  
	           Master master = new Master();  
	           Cat cat = new Cat();  
	           cat.Regiester(mouse);  
	           cat.Regiester(master);  
	           cat.Cry();  
	           Console.ReadLine();
	
	这样就实现了观察者模式,通过把依赖类注册到主体类中,当主体类发生变化时,所有依赖类都得到了通知。如果需要扩展,比如说象上面例子的狗也叫了,我们可以定义一个狗类,然后在主程序中把狗对象注册到猫类中就可以了。如果不想依赖于猫类,也可以通过UnRegiester方法取消绑定。
	同时,这也符合设计中的高内聚,低耦合的原则。
	。
复制代码 代码如下:
	
	using System;
	using System.Collections.Generic;
	using System.Text;
	namespace Sample
	{
	    public delegate void CatCallEventHandler();
	    class Program
	    {
	        static void Main(string[] args)
	        {
	            Cat cat = new Cat();
	            Mouse mouse = new Mouse(cat);
	            Master master = new Master(mouse);
	            cat.Call();
	        }
	    }
	    class Cat
	    {
	        public event CatCallEventHandler catevent;
	        public void Call()
	        {
	            Console.WriteLine("喵喵.....");
	            catevent();
	        }
	    }
	    class Mouse
	    {
	        public event CatCallEventHandler mouseevent;
	        public Mouse(Cat cat)
	        {
	            cat.catevent += new CatCallEventHandler(this.MouseRun);
	        }
	        public void MouseRun()
	        {
	            Console.WriteLine("老鼠跑");
	            mouseevent();
	        }
	    }
	    class Master
	    {
	        public Master(Mouse mouse)
	        {
	            mouse.mouseevent+=new CatCallEventHandler(this.JingXing);
	        }
	        public void JingXing()
	        {
	            Console.WriteLine("主人被惊醒");
	        }
	    }
	}
dy("nrwz");