首页 > 代码库 > 设计模式之观察者模式
设计模式之观察者模式
观察者模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己
1. Subject是对主题的抽象,但具体维护通知对象是在子类ConcreteSubject的实现中,ConcreteSubject调用它的notify来遍历通知对象。
2. ConcreteSubject是具体的主题,也是我们关心的对象,当它的subjectState修改的时候,同时调用父类的notify.实现通知
3. 当一个对象需要通知或改变其它对象,而它又不能假定其它对象是谁,也就是说 ,不希望这些对象是紧耦合的,我们就可能考虑它
观察者模在通信的具体实现中,有两个版本。
1) 拉模式:目标角色在发生变化后,仅仅告诉观察者角色“我变化了”;观察者角色如果想要知道具体的变化细节,则就要自己从目标角色的接口中得到。拉模式是想要就主动表白获取。这里存在依赖,观察者要依赖具体的主题 。
2) 推模式:通知你发生变化的同时,通过一个参数将变化的细节传递到观察者角色中去。推模式是管你要不要,先给你啦。推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况
而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要
以下是拉模式 代码如下: 实现的逻辑:当门打开时,主卧和客厅的灯亮起,电视打开。
/// <summary> /// 抽象主题 /// </summary> public abstract class Subject { private List<Observer> observers = new List<Observer>(); public void Add(Observer observer) { observers.Add(observer); } public void Remove(Observer observer) { observers.Remove(observer); } /// <summary> /// 通知所有观察者 /// </summary> public void Notify() { observers.ForEach(o => o.Action(this)); } } public class Door :Subject { public string DoorState { get; set; } public void Open() { this.DoorState = "开启"; Console.WriteLine(string.Format("门开起")); base.Notify(); } } public abstract class Observer { public abstract void Action(Subject subject); } public class Light : Observer { private string name; public Light(string name) { this.name = name; } public override void Action(Subject subject) { var door = (Door)subject; Console.WriteLine(string.Format("门{0},{1}灯 亮起",door.DoorState, this.name)); } } public class TV : Observer { public override void Action(Subject subject) { Console.WriteLine(string.Format("TV 打开")); } } class Program { static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; Observer masterRoom = new Light("主卧室"); Observer LivingRoom = new Light("客厅"); Observer tv = new TV(); Door door = new Door(); door.Add(masterRoom); door.Add(LivingRoom); door.Add(tv); door.Open(); Console.ReadKey(); } }
C# 提供了事件的机制,同样可以实现观察者模式,与上面代码稍有不同:
//继承自EventArgs //用作保存状态,还可以扩展其他的功能 public class StateChangeEventArgs : EventArgs { public string State { get; set; } public StateChangeEventArgs(string state) { this.State = state; } } //定义一个委托 public delegate void StateChangeEventHandler(object sender, StateChangeEventArgs e); public class Door { public event StateChangeEventHandler StateChange; public string DoorState { get; set; } public void Open() { this.DoorState = "开启"; Console.WriteLine(string.Format("门开起")); StateChangeEventArgs e = new StateChangeEventArgs(this.DoorState); StateChange(this, e); } } public abstract class Observer { public abstract void Action(object sender, StateChangeEventArgs e); } public class Light : Observer { private string name; public Light(string name) { this.name = name; } public override void Action(object sender, StateChangeEventArgs e) { Console.WriteLine(string.Format("门{0},{1}灯 亮起", e.State, this.name)); } } public class TV : Observer { public override void Action(object sender, StateChangeEventArgs e) { Console.WriteLine(string.Format("TV 打开")); } } class Program { static void Main(string[] args) { Console.OutputEncoding = Encoding.UTF8; Observer masterRoom = new Light("主卧室"); Observer livingRoom = new Light("客厅"); Observer tv = new TV(); Door door = new Door(); door.StateChange += masterRoom.Action; door.StateChange += livingRoom.Action; door.StateChange += tv.Action; door.Open(); Console.ReadKey(); } }
设计模式之观察者模式