首页 > 代码库 > 发布-订阅模式(观察者模式)
发布-订阅模式(观察者模式)
(一)什么是观察者模式
发布-订阅,这两个词语是对观察者的最好解释,现实生活中,这样的案例有很多,比如在篮球比赛过程中教练,喊一个暂停,然后球员和裁判都做相关的响应,还有比如OA里面发布的放假通知等等。无论是篮球比赛,还是OA的通知,都存在一个角色,它的作用就是保持对相关问题的关注,在问题发生变化的时候,是Ta把消息通知给相关各方。观察者模式也差不多这样,它抽象一类对象(观察者)专门负责"盯着"目标对象,当目标对象状态有变动的时候,每个观察者就会获得通知并迅速做出响应,观察者模式解决的也是调用通知关系所带来的依赖。
(二)观察者模式的演变
下面请看代码。有三个类,A,B,C想接收来自X的消息,简单的说X发生变化,他们也跟着变化。
public class A { public int Data; public void Update(int data) { this.Data =http://www.mamicode.com/ data; } } public class B { public int Count; public void NotifyCount(int data) { this.Count = data; } } public class C { public int N; public void Set(int data) { this.N = data; } } //上面这三个类,类A,B,C是希望获得X通知的类型 public class X { private int data; public A InstanceA; public B InstanceB; public C InstanceC; public void SetData(int data) { this.data =http://www.mamicode.com/ data; InstanceA.Update(data); InstanceB.NotifyCount(data); InstanceC.Set(data); } }
在我们调用的时候,应该这么做
A a = new A(); B b = new B(); C c = new C(); X x = new X(); x.InstanceA = a; x.InstanceB = b; x.InstanceC = c; x.SetData(10); Console.WriteLine("x发出消息了"); Console.WriteLine(a.Data); Console.WriteLine(b.Count); Console.WriteLine(c.N);
对于上面这种做法,大家应该都会。下面是这个上面例子的类图关系,从这里,我们可以看得X和太多类直接关联了。已经很不符合面向对象的设计原则了。
经过观察,我们发现类A,B,C都有个共同之处,都是有一个类似于更新的方法,如果对他们进行抽象的话呢,就可以让类X仅仅依赖于一个抽象的类型。下面直接看代码
public interface IUpdatableObject { int Data {get;} void Update(int newData); } public class A : IUpdatableObject { private int data; public int Data { get { return this.data; } } public void Update(int newData) { this.data =http://www.mamicode.com/ newData; } } public class B : IUpdatableObject { private int data; public int Data { get { return this.data; } } public void Update(int newData) { this.data =http://www.mamicode.com/ newData; } } public class C : IUpdatableObject { private int data; public int Data { get { return this.data; } } public void Update(int newData) { this.data =http://www.mamicode.com/ newData; } } public class X { private IUpdatableObject[] objects = new IUpdatableObject[3]; //这个是索引器的用法 public IUpdatableObject this[int index] { set { objects[index] = value; } } private int data; public void Update(int newData) { this.data =http://www.mamicode.com/ newData; foreach(IUpdatableObject obj in objects) { obj.Update(newData); } } }
//调用代码如下
X x = new X(); IUpdatableObject a = new A(); IUpdatableObject b = new B(); IUpdatableObject c = new C(); x[0] = a; x[1] = b; x[2] = c; x.Update(10); Console.WriteLine("x发出了消息"); Console.Write(a.Data); Console.Write(b.Data); Console.Write(c.Data);
通过上面我们就可以依赖于抽象了,比如当我们要新增加一个订阅者的时候,也不用去类X里面改内部代码,请看类图。
今天先讲到这里,下一篇文章很快就会出,欢迎大家多多指点。
发布-订阅模式(观察者模式)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。