意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性
1.当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性
1.当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。


程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)
要求:
1.要有联动性,老鼠和主人的行为是被动的。
2.考虑可扩展性,猫的叫声可能引起其他联动效应。
using System;
using System.Collections.Generic;
namespace Observer
{
/// <summary>
/// 观察着接口定义
/// </summary>
public interface IObserver
{
/// <summary>
/// 每个观察着都有一个响应(Response)方法
/// <para>表示当被观察的状态发生变化时</para>
/// <para>观察着的所作出的反应</para>
/// <para>相当与结构图中观察着的 Update 方法</para>
/// </summary>
void Response();
}//End interface IObserver
/// <summary>
/// 被观察着接口定义
/// </summary>
public interface ISubject
{
/// <summary>
/// 被观察者与指定的观察进行绑定
/// </summary>
/// <param name="observer"></param>
void Attach(IObserver observer);
/// <summary>
/// 被观察着与指定的观察着解除已有的绑定关系
/// </summary>
/// <param name="observer"></param>
void Detach(IObserver observer);
/// <summary>
/// 当被观察着的状态发生变化时
/// <para>通过调用此方法通知所有与该被观察者建立关系的观察着</para>
/// <para>以便观察着做出特有的更新或响应</para>
/// </summary>
void Notify();
}//End interface ISubject
/// <summary>
/// 定义猫类,实现被观察着接口
/// </summary>
public class Cat : ISubject
{
/// <summary>
/// 观察着列表
/// </summary>
List<IObserver> observers;
/// <summary>
/// 简单标识:猫的名称
/// </summary>
string name;
/// <summary>
/// 初始化一只猫
/// </summary>
/// <param name="name">名称</param>
public Cat(string name)
{
this.name = name;
this.observers = new List<IObserver>();
}
/// <summary>
/// 猫叫
/// </summary>
public void Cry()
{
Console.WriteLine("猫叫将引起的反应:");
this.Notify();
}
/// <summary>
/// 与指定的观察着建立观察关系
/// </summary>
/// <param name="observer">观察着</param>
public void Attach(IObserver observer)
{
if (!observers.Contains(observer))
observers.Add(observer);
}
/// <summary>
/// 与指定的观察着解除观察关系
/// </summary>
/// <param name="observer">观察着</param>
public void Detach(IObserver observer)
{
if (observers.Contains(observer))
observers.Remove(observer);
}
/// <summary>
/// 当猫的状态有所变化时,通知所有绑定的观察着
/// </summary>
public void Notify()
{
foreach (IObserver observer in this.observers)
observer.Response();
}
}//End class Cat
/// <summary>
/// 定义老鼠类,实现观察着接口
/// </summary>
public class Mouse : IObserver
{
/// <summary>
/// 老鼠的标识系列号
/// </summary>
int flag = -1;
/// <summary>
/// 初始化一只老鼠
/// </summary>
/// <param name="flag"></param>
public Mouse(int flag)
{
this.flag = flag;
}
public void Response()
{
Console.WriteLine("第 {0} 只老鼠开始逃跑!", flag);
}
}//End class Mouse
/// <summary>
/// 定义主人类,实现观察着接口
/// </summary>
public class Master : IObserver
{
/// <summary>
/// 主人名称
/// </summary>
string name = String.Empty;
/// <summary>
/// 初始化主人
/// </summary>
/// <param name="name"></param>
public Master(string name)
{
this.name = name;
}
public void Response()
{
Console.WriteLine("主人 {0} 被吵醒!", name);
}
}//End class Master
/// <summary>
/// 测试类
/// </summary>
public class Test
{
public static void Main()
{
Master master = new Master("唐伯虎");
Cat cat = new Cat("David");
Mouse mouse1 = new Mouse(1);
Mouse mouse2 = new Mouse(2);
Mouse mouse3 = new Mouse(3);
Mouse mouse4 = new Mouse(4);
Mouse mouse5 = new Mouse(5);
//猫与主人及众多老鼠建立观察关系
cat.Attach(master);
cat.Attach(mouse1);
cat.Attach(mouse2);
cat.Attach(mouse3);
cat.Attach(mouse4);
cat.Attach(mouse5);
cat.Cry();//猫叫
}
}//End class Test
}
程序运行结果:

注意:在观察着设计模式中,往往存在一个被观察事物的焦点对象,当该对象的状态发生变化时,与之建立观察关系的所有观察着都将做出特有的反应。
浙公网安备 33010602011771号