**定义:**观察者模式(ObserverPattern),定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
类型:对象行为型模式
概述:
观察者模式也是比较难以理解,单看类图,会发现观察者模式与中介模式非常相似。如果不真正理解他们二者之间的区别,是难以真正理解观察者模式的。如果不理解观察者模式,更奢谈运用观察者模式了。
中介模式主要是解决一系列交互对象的耦合的问题,而提出了中介类。几个以前交互的对象现在统一通过中介类来完成交流。而观察者模式侧重的是一对多的通知的功能,即当发生某件事时,主题对象将向所有注册过的观察者对象发出通知消息。
中介模式侧重通过中介类来完成交流;而观察者模式侧重于一对多的通知。中介模式不需要知道具体的中介类的对象,需要交互的对象只需要知道一个通知中介对象的接口即可,具体是哪个中介来完成交互对象告诉的任务,交互对象不需要知道。但是交互对象必须知道有哪些交互对象,这样才能把对象A需要对象B做的事想办法通知到对象B。
观察者模式则,Subject对象不需要知道具体的观察者是谁,它只需要知道观察者的通知接口,就可以将消息通知到观察者。至于具体有哪些消息,则需要观察者自己去具体的Subject那里查看。
这里举一个例子,某电商有大促销,通过邮件发送促销消息给消费者。但是如果消费者想了解有哪些具体的促销信息,则即需要亲自去电商网站查看有哪些具体的促销信息。
类图:
![](https://box.kancloud.cn/2016-08-19_57b6b467733f3.jpg)
**参与者:**
1. Vender,提供接口来完成对观察者的注册通知。
1. YiXun,具体的电商,为消费者提供所需要查看具体信息。
1. Observer,提供Update接口。
1. CustomerA、CustomerB,具体的观察者,当有更新时去查看电商中自己喜欢的产品。
**示例代码:**
~~~
using System;
using System.Collections.Generic;
using System.Text;
namespace Design20
{
abstract class Vender
{
private IList<Observer> observers = new List<Observer>();
// 观察者注册
public void Register(Observer observer)
{
observers.Add(observer);
}
//通知
public void Notify()
{
foreach (Observer o in observers)
{
o.Update();
}
}
}
//具体通知者
class YiXun : Vender
{
private string subjecPhone;
private string subjecLaptop;
//具体通知者状态
public string SubjecPhone
{
get { return subjecPhone; }
set { subjecPhone = value; }
}
//具体通知者状态
public string SubjecLaptop
{
get { return subjecLaptop; }
set { subjecLaptop = value; }
}
}
abstract class Observer
{
public abstract void Update();
}
class CustomerA : Observer
{
private YiXun subject;
public CustomerA(
YiXun subject)
{
this.subject = subject;
}
//更新
public override void Update()
{
Console.WriteLine("消费者A查看到的是{0}", this.subject.SubjecPhone);
}
public YiXun Subject
{
get { return subject; }
set { subject = value; }
}
}
class CustomerB : Observer
{
private YiXun subject;
public CustomerB(
YiXun subject)
{
this.subject = subject;
}
//更新
public override void Update()
{
Console.WriteLine("消费者B查看到的是{0}", this.subject.SubjecLaptop);
}
public YiXun Subject
{
get { return subject; }
set { subject = value; }
}
}
class Program
{
static void Main(string[] args)
{
YiXun subject = new YiXun();
subject.Register(new CustomerA(subject));
subject.Register(new CustomerB(subject));
// 来了新手机和新笔记本电脑,然后通知到所有注册的消费者.
// 然后消费者去查看自己感兴趣的产品有哪些.
subject.SubjecPhone = "IPhone5s";
subject.SubjecLaptop = "ThinkPad";
subject.Notify();
Console.Read();
}
}
}
~~~
**适用性:**
1. 一组对象以定义良好但是复杂的方式进行通信。产生的相互依赖关系结构混乱且难以理解。
1. 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象。
1. 想定制一个分布在多个类中的行为,而又不想生成太多的子类。
优缺点:
1. 优点,降低命令发起者与命令接受者之间的耦合,发布者通过接口通知所有观察者。
1. 缺点,具体的观察者依赖了具体的发布者。
参考资料:
1. 《设计模式——可复用面向对象软件基础》
1. 《大话设计模式》
- 前言
- 设计模式六大原则
- 1——创建型模式之简单工厂模式
- 2——创建型模式之工厂方法模式
- 3——创建型模式之抽象工厂模式
- 4——创建型模式之单例模式
- 5——创建型模式之建造者模式
- 6——创建型模式之原型模式
- 7——结构型模式之适配器模式
- 8——结构型模式之桥接模式
- 9——结构型模式之组合模式
- 10——结构型模式之装饰者模式
- 11——结构型模式之外观模式
- 12——结构型模式之享元模式
- 13——结构型模式之代理模式
- 14——行为型模式之职责链模式
- 15——行为型模式之命令模式
- 16——行为型模式之解释器模式
- 17——行为型模式之迭代器模式
- 18——行为型模式之中介者模式
- 19——行为型模式之备忘录模式
- 20——行为型模式之观察者模式
- 21——行为型模式之状态模式
- 22——行为型模式之策略模式
- 23——行为型模式之模板方法模型
- 24——行为型模式之访问者模式
- 设计模式总结