要求: 1.要有聯動性,老鼠和主人的行爲是被動的。ide
2.考慮可擴展性,貓的叫聲可能引發其餘聯動效應。函數
我麼能事件來一步一步來實現: 將要執行的老鼠逃跑,和主人驚醒的行爲註冊到事件中,貓叫以後引起事件的執行!this
一、聲明一個委託spa
namespace ConsoleTest.MouseAndCat { public delegate void Delegate(); }
二、由於是由貓叫引起的事件執行,全部事件聲明在貓類中code
namespace ConsoleTest.MouseAndCat { public class Cat { public event Delegate Eventhandler;
public void FireAway() { if (this.Eventhandler != null) { this.Eventhandler(); } } } }
三、下面寫(老鼠,主人),對其類實例化時,將要執行的行爲註冊到事件中server
namespace ConsoleTest.MouseAndCat { public class Master { public Master(Cat cat) { cat.Eventhandler += new Delegate(Action); } public void Action() { Console.WriteLine("主人聽見了!"); } } public class Mouse { public Mouse(Cat cat) { cat.Eventhandler += new Delegate(Action); } public void Action() { Console.WriteLine("老鼠聽見了,逃跑!"); } } }
四、執行,執行cat的FireAwayAndWakeup方法,內部執行已註冊到事件的方法對象
static void Main(string[] args) { Cat cat = new Cat(); Mouse mouse = new Mouse(cat); Master master = new Master(cat); cat.FireAway(); }
---------------------------------------------------------------------------------------------blog
提升一:以上已經實現了,可是考慮到可擴展性,再看第3部分的兩個類中,都是在構造函數中註冊事件,而且有一個執行的方法,那麼若是再擴展其餘的功能,好比,鄰居聽見...等。都須要再寫相同的代碼,全部咱們有必要爲觀察者(貓叫以後,所引起的對象)提供一個父類或者接口,來統一標準,可是由於觀察者都是在構造函數中進行事件的註冊,而註冊到事件中的方法所作的事件不一樣(例:老鼠逃跑、主人等),因此咱們來建立一個父類(既有接口的功能,也有具體的事件),抽象類,又它來做爲觀察者的父類接口
public abstract class Observer { public Observer(Cat cat) { cat.Eventhandler+=new Delegate(Action); } public abstract void Action(); }
那麼觀察者的類中的也要有相應的變更事件
public class Master:Observer { public Master(Cat cat):base(cat) //執行父類中的構造函數,而且將此派生類中的方法在父類的構造函數中註冊到事件中 { } public override void Action() //重寫抽象類中的抽象方法 { Console.WriteLine("主人聽見了!"); } } public class Mouse:Observer { public Mouse(Cat cat):base(cat) //執行父類中的構造函數,而且將此派生類中的方法在父類的構造函數中註冊到事件中 {} public override void Action() { Console.WriteLine("老鼠聽見了,逃跑!"); } }
這樣一來,再對觀察者進行相應的擴展的時候也就省去了些許的步驟,若是觀察者多了的話,優勢之處就會更加明顯了。
----------------------------------------------------------------------------------------------------
提升二:咱們再對第2部分進行改進,這裏是由 貓叫 引起的一系列的行爲,可是若是咱們以後又想添加 狗叫 引起這些行爲的話,那麼就須要再重寫第2部分的那些代碼,本着可擴展的目的,咱們爲這些引起行爲的 引起者(貓、狗) 添加一個父類,父類中去實現引起事件的執行,而其派生類(阿貓、阿狗),只負責去調用其父類中的方法便可..
public abstract class Subject { public event Delegate Eventhandler; public void FireAway() { if (this.Eventhandler != null) { this.Eventhandler(); } } }
那麼 引起者 只須要調用父類中的FireAway方法去執行已註冊在事件中的方法便可。
public class Cat { public void Cry() { this.FireAway(); } } public class Dog { public void Cry() { this.FireAway(); } }
值得注意的是,觀察者 的構造函數中的參數類型,要改成引起者的父類:Subject 。由於不止能夠將引起的行爲(老鼠逃跑、主人醒等)添加到貓引起的事件中,還能夠將其添加到狗引起的事件中。
因此整個部分應該爲:
namespace ConsoleTest.MouseAndCat { public delegate void Delegate(); }
public abstract class Subject { public event Delegate Eventhandler; public void FireAway() { if (this.Eventhandler != null) { this.Eventhandler(); } } } public class Cat:Subject { public void Cry() { this.FireAway(); } } public class Dog:Subject { public void Cry() { this.FireAway(); } }
public abstract class Observer { public Observer(Subject sub) { sub.Eventhandler += new Delegate(Action); } public abstract void Action(); } public class Master:Observer { public Master(Subject sub):base(sub) { } public override void Action() { Console.WriteLine("主人聽見了!"); } } public class Mouse:Observer { public Mouse(Subject sub): base(sub) {} public override void Action() { Console.WriteLine("老鼠聽見了,逃跑!"); } }
static void Main(string[] args) { Cat cat = new Cat(); Mouse mouse = new Mouse(cat); Master master = new Master(cat); cat.Cry(); Dog dog = new Dog(); Mouse dog_mouse = new Mouse(dog); Master dog_master = new Master(dog); dog.Cry(); Console.ReadKey(); }
OK...