观察者模式的理解。
一、对象
1.观察者Observer
2.被观察者Subject
二、动作
观察者-------(action 观察)------>被观察者
被观察者自身发生改变
观察者得到被观察者改变之后的信息,
很多网上的列子,都是被观察者去注册观察者,这感觉有点本末倒置,
被观察者是被动的,它唯一主动的操作就是改变它自己的状态。
而主动的是观察者,应该由观察者去主动订阅被观察者。
三、从类的角度来理解
画图的类图应该是:
四、从类关系图来看
Observer和Subject是多对多的关系
Observer代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace observerPattern { public abstract class Observer { public Observer() { this.SubjectCollection = new HashSet<Subject>(); } public string Name { get; set; } public virtual void Display() { } public void Subscribe(Subject subject) { this.SubjectCollection.Add(subject); subject.Attach(this); } public void UnSubscribe(Subject subject) { this.SubjectCollection.Remove(subject); subject.Detach(this); } public ICollection<Subject> SubjectCollection { get; set; } } }
Subject代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace observerPattern { public abstract class Subject { public Subject() { this.ObserverCollecion = new HashSet<Observer>(); } public string Name { get; set; } public string Message { get; set; } public void Attach(Observer observer) { this.ObserverCollecion.Add(observer); } public void Detach(Observer observer) { this.ObserverCollecion.Remove(observer); } public void Change() { throw new System.NotImplementedException(); } public ICollection<Observer> ObserverCollecion { get; set; } } }
然后拿经典的例子猫叫老鼠跑来分析
Cat代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace observerPattern { public class Cat : Subject { public Cat(string name, string message) { this.Name = name; this.Message = message; Console.WriteLine(this.Name + "信息:" + this.Message); } public void Change() { this.Message = "饿了,醒来了"; foreach (var o in this.ObserverCollecion) { o.Display(); } } } }
老鼠Mouse代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace observerPattern { public class Mouse : Observer { public Mouse(string name) { this.Name = name; } public override void Display() { Console.WriteLine(this.Name + ":订阅详情"); foreach (var s in this.SubjectCollection) { Console.WriteLine("订阅者:" + s.Name + ",订阅信息:" + s.Message); } SelfAction(); } public void SelfAction() { Console.WriteLine("快跑!"); } } }
主进程代码:
class Program { static void Main(string[] args) { Cat ct = new Cat("猫", "睡着的"); Mouse mo = new Mouse("小老鼠"); mo.Subscribe(ct); ct.Change(); Console.ReadLine(); } }
事件驱动的observer pattern代码:
Observer代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace observerPatternEvent { public abstract class Observer { public Observer() { this.SubjectCollection = new HashSet<Subject>(); } public string Name { get; set; } public virtual void Display(Object sender, EventArgs e) { } public void Subscribe(Subject subject) { this.SubjectCollection.Add(subject); subject.MessageChanged += Display; } public void UnSubscribe(Subject subject) { this.SubjectCollection.Remove(subject); subject.MessageChanged -= Display; } public ICollection<Subject> SubjectCollection { get; set; } } }
Subject代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace observerPatternEvent { public abstract class Subject { public string Name { get; set; } public string Message { get; set; } public event EventHandler MessageChanged; public virtual void Change(string message) { this.Message = message; if (MessageChanged != null) MessageChanged(this, EventArgs.Empty); } } }
Cat代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace observerPatternEvent { public class Cat : Subject { public Cat(string name, string message) { this.Name = name; this.Message = message; Console.WriteLine(this.Name + "信息:" + this.Message); } } }
Mouse代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace observerPatternEvent { public class Mouse : Observer { public Mouse(string name) { this.Name = name; } public override void Display(object sender, EventArgs e) { Console.WriteLine(this.Name + ":订阅详情"); foreach (var s in this.SubjectCollection) { Console.WriteLine("订阅者:" + s.Name + ",订阅信息:" + s.Message); } SelfAction(); } public void SelfAction() { Console.WriteLine("快跑!"); } } }
主程序:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace observerPatternEvent { class Program { static void Main(string[] args) { Cat ct = new Cat("猫", "睡着的"); BlackCat ct1 = new BlackCat("黑猫", "睡着的"); Mouse mo = new Mouse("小老鼠"); mo.Subscribe(ct); mo.Subscribe(ct1); ct.Change("睡醒了,饿了"); mo.UnSubscribe(ct); ct1.Change("继续睡"); Console.ReadLine(); } } }