观察者模式中主要角色:
1.抽象主题角色:主题角色将所有对观察者对象的引用保存在一个聚集里,每一个主题都可以有任意多的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又可以叫成是抽象被观察者角色,一般用一个抽象类或者是一个接口来实现。
2.抽象观察者角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这一个接口也可以称为更新接口,抽象观察者角色一般用一个抽象类或者是一个接口实现,在这个示意性的实现中,更新接口只包含一个方法(更新方法)。
3.具体主题角色:将有关状态存入具体观察者对象;在具体主题的内部状态发生变化时,给所有的登记过的观察者发出通知,具体主题又可以称为 是具体被观察者角色。具体被观察者角色一般用一个具体的子类来实现。
4.具体观察者:存储与主题的状态自洽的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,一边是本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色常用一个具体子类实现。
从具体主题角色指向抽象观察者角色的合成关系,代表具体主题对象可以有任意多个对抽象观察者对象的引用。之所以使用抽象观察者而不是具体观察者,意味着主题对象不需要知道引用了哪些类型,而只知道抽象Observer'类型。这就使得具体主题对象可以动态的维护一系列的对观察者对象的引用,并在需要的时候调用每一个观察者共有的Update方法。这种做法称为针对抽象编程。
以下是一个非常典型的例子:猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。要求是:一要有联动性,老鼠和主人的行为是被动的,二要考虑可扩展性,猫的叫声可能引起其他的联动效应。
以下是程序:仅供参考
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ObserverTest
{
public interface Observer
{
void response();
}
public interface Subject
{
void AmiA(Observer obs);
}
public class Mouse : Observer
{
private string name;
public Mouse(string name, Subject subj)
{
this.name = name;
subj.AmiA(this);
}
public void response()
{
Console.WriteLine(name + "attempt to escaped!");
}
}
public class Master : Observer
{
public Master(Subject subj)
{
subj.AmiA(this);
}
public void response()
{
Console.WriteLine("host woken");
}
}
public class Cat : Subject
{
private ArrayList observers;
public Cat()
{
observers = new ArrayList();
}
public void AmiA(Observer obs)
{
this.observers.Add(obs);
}
public void cry()
{
Console.WriteLine("cat cryed!");
foreach (Observer o in observers)
{
o.response();
}
}
}
class Program
{
static void Main(string[] args)
{
Cat cat = new Cat();
Mouse mouse1 = new Mouse("mouse1", cat);
Mouse mouse2 = new Mouse("mouse2",cat);
Master maste = new Master(cat);
cat.cry();
}
}
}