C#设计模式系列:观察者模式(Observer)

时间:2023-03-10 01:27:30
C#设计模式系列:观察者模式(Observer)

  在软件构建过程中,需要为某些对象建立一种“通知依赖关系”,即一个对象的状态发生改变,所有的依赖对象都需要得到通知。

1、观察者模式简介

1.1>、定义

  定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

1.2>、使用频率

  C#设计模式系列:观察者模式(Observer)

2、观察者模式结构

2.1>、结构图

C#设计模式系列:观察者模式(Observer)

2.2>、参与者

  观察者模式参与者:

  ◊ Subject

    ° 抽象的主题,被观察的对象

    ° 提供Attach和Detach Observer对象的接口

  ◊ ConcreteSubject

    ° 具体的被观察对象,维持ConcreteSubject状态。

    ° 当状态发生变化时,发送消息通知它的观察者。

  ◊ Observer:抽象的观察者,定义一个发送变化通知更新的接口。

  ◊ ConcreteObserver

    ° 维持一个对ConcreteSubject对象的引用

    ° 保存subjects状态

    ° 实现当Observer接口发生变动时,subjects状态同步更新。

  在观察者模式中,Subject通过Attach()和Detach()方法添加或删除其所关联的观察者,并通过Notify进行更新,让每个观察者都可以观察到最新的状态。

3、观察者模式结构实现

C#设计模式系列:观察者模式(Observer)

  Observer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.ObserverPattern.Structural
{
public abstract class Observer
{
public abstract void Update();
}
}

  Subject.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.ObserverPattern.Structural
{
public class Subject
{
private List<Observer> _observers = new List<Observer>(); public void Attach(Observer observer)
{
_observers.Add(observer);
} public void Detach(Observer observer)
{
_observers.Remove(observer);
} public void Notify()
{
foreach (Observer o in _observers)
{
o.Update();
}
}
}
}

  ConcreteSubject.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.ObserverPattern.Structural
{
public class ConcreteSubject : Subject
{
private string _subjectState; /// <summary>
/// Gets or sets subject state
/// </summary>
public string SubjectState
{
get { return _subjectState; }
set { _subjectState = value; }
}
}
}

  ConcreteObserver.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.ObserverPattern.Structural
{
public class ConcreteObserver : Observer
{
private string _name;
private string _observerState;
private ConcreteSubject _subject; public ConcreteObserver(ConcreteSubject subject, string name)
{
this._subject = subject;
this._name = name;
} public override void Update()
{
_observerState = _subject.SubjectState;
Console.WriteLine("Observer {0}'s new state is {1}", _name, _observerState);
} public ConcreteSubject Subject
{
get { return _subject; }
set { _subject = value; }
}
}
}

  Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; using DesignPatterns.ObserverPattern.Structural; namespace DesignPatterns.ObserverPattern
{
class Program
{
static void Main(string[] args)
{
// Configure Observer pattern
ConcreteSubject s = new ConcreteSubject(); s.Attach(new ConcreteObserver(s, "X"));
s.Attach(new ConcreteObserver(s, "Y"));
s.Attach(new ConcreteObserver(s, "Z")); // Change subject and notify observers
s.SubjectState = "ABC";
s.Notify();
}
}
}

  运行输出:

Observer X's new state is ABC
Observer Y's new state is ABC
Observer Z's new state is ABC
请按任意键继续. . .

4、观察者模式应用分析

  观察者模式适用情形:

  ◊ 当一个抽象模型有两个方面,其中一方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。

  ◊ 当对一个对象的改变需要同时改变其他对象,而不需要知道具体有多少对象有待改变。

  ◊ 当一个对象必须通知其他对象,而它又不需要知道其它的通知对象是谁,那些其它对象是谁不影响它发送通知这件事。

  观察者模式特点:

  ◊ 使用面向对象的抽象,Observer模式使得可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合。

  ◊ 目标发送通知时,无需指定观察者,通知会自动传播。观察者自己决定是否需要订阅通知。

  ◊ 在C#中的Event。委托充当了Observer接口,而提供事件的对象充当了目标对象,委托是比抽象Observer接口更为松耦合的设计。