我读设计模式之观察者模式(Observer Pattern)
观察者模式关注一个一对多的依赖关系:当一个对象发生变化时,多个与其有关联的对象都要被通知到,并更新自己。
有一个题目:猫叫,主人醒,老鼠跑。通常我们用事件委托方式来解决这个问题。但想来,这个场景很有点观察者模式的味道。
观察者模式通常包括四个角色:
1 抽象通知者
2 具体通知者
3 抽象观察者
4 具体观察者
一个简单的例子:秘书看到老板回来,通知“不务正业”的同志。
using System;
using System.Collections.Generic;
using System.Text;
namespace Demo4
{
class Program
{
static void Main(string[] args)
{
secretary sec = new ConcreteSecretary("Bass is coming");
sec.Add(new NBAObserver("ivan",sec));
sec.Add(new NewsObserver("ashley",sec));
sec.notify();
Console.Read();
}
}
public abstract class secretary //抽象通知者
{
private string _subject;
public string Subject
{
get { return _subject; }
set { _subject = value; }
}
public secretary(string subject)
{
this._subject = subject;
}
List<IObserver> Observers = new List<IObserver>();
//增加通知者
public void Add(IObserver observer)
{
Observers.Add(observer);
}
//删除通知者
public void Remove(IObserver observer)
{
Observers.Remove(observer);
}
//通知
public void notify()
{
foreach (IObserver ob in Observers)
{
ob.update();
}
}
}
//具体通知者
public class ConcreteSecretary:secretary
{
public ConcreteSecretary(string subject)
:base(subject)
{ }
}
public interface IObserver //抽象观察者
{
void update();
}
public class NBAObserver : IObserver //具体观察者(NBA Observer)
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private secretary _secretary;
public secretary Secretary
{
get { return _secretary; }
set { _secretary = value; }
}
public NBAObserver(string name, secretary secr)
{
this._name = name;
this._secretary = secr;
}
public void update()
{
Console.WriteLine(_secretary.Subject+"--" + _name+ " please close games and began to work");
}
}
//扩展具体的通知者,只需要新增具体类即可
public class NewsObserver : IObserver //具体观察者(News Observer)
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private secretary _secretary;
public secretary Secretary
{
get { return _secretary; }
set { _secretary = value; }
}
public NewsObserver(string name, secretary secr)
{
this._name = name;
this._secretary = secr;
}
public void update()
{
Console.WriteLine(_secretary.Subject + "--" + _name + " please shut down the news");
}
}
}
using System.Collections.Generic;
using System.Text;
namespace Demo4
{
class Program
{
static void Main(string[] args)
{
secretary sec = new ConcreteSecretary("Bass is coming");
sec.Add(new NBAObserver("ivan",sec));
sec.Add(new NewsObserver("ashley",sec));
sec.notify();
Console.Read();
}
}
public abstract class secretary //抽象通知者
{
private string _subject;
public string Subject
{
get { return _subject; }
set { _subject = value; }
}
public secretary(string subject)
{
this._subject = subject;
}
List<IObserver> Observers = new List<IObserver>();
//增加通知者
public void Add(IObserver observer)
{
Observers.Add(observer);
}
//删除通知者
public void Remove(IObserver observer)
{
Observers.Remove(observer);
}
//通知
public void notify()
{
foreach (IObserver ob in Observers)
{
ob.update();
}
}
}
//具体通知者
public class ConcreteSecretary:secretary
{
public ConcreteSecretary(string subject)
:base(subject)
{ }
}
public interface IObserver //抽象观察者
{
void update();
}
public class NBAObserver : IObserver //具体观察者(NBA Observer)
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private secretary _secretary;
public secretary Secretary
{
get { return _secretary; }
set { _secretary = value; }
}
public NBAObserver(string name, secretary secr)
{
this._name = name;
this._secretary = secr;
}
public void update()
{
Console.WriteLine(_secretary.Subject+"--" + _name+ " please close games and began to work");
}
}
//扩展具体的通知者,只需要新增具体类即可
public class NewsObserver : IObserver //具体观察者(News Observer)
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private secretary _secretary;
public secretary Secretary
{
get { return _secretary; }
set { _secretary = value; }
}
public NewsObserver(string name, secretary secr)
{
this._name = name;
this._secretary = secr;
}
public void update()
{
Console.WriteLine(_secretary.Subject + "--" + _name + " please shut down the news");
}
}
}
当然,用观察者模式实现的通知功能,用代理也可以轻松实现。下面的代码就用代理机制实现相同的功能。
Code
Observer模式的优点是实现了表示层和数据逻辑层的分离,并定义了稳定的更新消息传递机制,类别清晰,并抽象了更新接口,使得可以有各种各样不同的表示层(观察者)。
学习参考:
http://www.cnblogs.com/Terrylee/archive/2006/10/23/537778.html