观察者模式

一、观察者模式简介

        观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化的时,会通知所有观察者对象,使他们能够自动更新自己。

二、解决的问题

         当一个对象的改变需要同时改变其他对象的时候,而且不知道有多少对象有待改变时,应该考虑使用观察者模式。观察者模式所做的工作其实就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使的各自的变化都不会影响另一边的变化。

三、观察者模式分析

下面通过一个例子来说明Observer模式。监控某一个公司的股票价格变化,可以有多种方式,通知的对象可以是投资者,或者是发送到移动设备,还有电子邮件等。为了降低耦合性,代码设计如下:

public abstract class Stock

{
    private List<IObserver> observers = new List<IObserver>();

    private String _symbol;

    private double _price;

    public Stock(String symbol, double price)

    {
        this._symbol = symbol;

        this._price = price;
    }

    public void Update()

    {
        foreach (IObserver ob in observers)

        {
            ob.SendData(this);
        }

    }

    public void AddObserver(IObserver observer)

    {
        observers.Add(observer);
    }

    public void RemoveObserver(IObserver observer)

    {
        observers.Remove(observer);
    }

    public String Symbol

    {
        get { return _symbol; }
    }

    public double Price

    {
        get { return _price; }
    }
}

public class Microsoft : Stock

{

    public Microsoft(String symbol, double price)

        : base(symbol, price)

    { }
}

public interface IObserver

{
    void SendData(Stock stock);
}

public class Investor : IObserver

{
    private string _name;

    public Investor(string name)

    {
        this._name = name;
    }

    public void SendData(Stock stock)

    {
        Console.WriteLine("Notified {0} of {1}'s " + "change to {2:C}", _name, stock.Symbol,stock.Price);

    }
}

客户端程序代码如下:

class Program
{
    static void Main(string[] args)

    {
        Stock ms = new Microsoft("Microsoft",120.00);

        ms.AddObserver(new Investor("Jom"));

        ms.AddObserver(new Investor("TerryLee"));

        ms.Update();

        Console.ReadLine();
   } }


从上面的代码可以看出,通过抽象类,将直接依赖变为了间接依赖,每一个具体的对象与具体的观察者都没有直接联系,这样大大提供了系统的可维护性和可扩展性。那还有没有更好的方式呢?利用事件和委托来实现Observer模式我认为更加的简单和优雅,也是一种更好的解决方案。看下面代码

class Program
{
    static void Main(string[] args)
    {
        Stock stock = new Stock("Microsoft", 120.00);

        Investor investor = new Investor("Jom");

        stock.NotifyEvent += new NotifyEventHandler(investor.SendData);

        stock.Update();

        Console.ReadLine();
    }
}

public delegate void NotifyEventHandler(object sender);


public class Stock

{
    public NotifyEventHandler NotifyEvent;

    private String _symbol;

    private double _price;

    public Stock(String symbol, double price)

    {
        this._symbol = symbol;

        this._price = price;
    }

    public void Update()

    {
        OnNotifyChange();    
    }

    public void OnNotifyChange()

    {
        if (NotifyEvent != null)

        {
            NotifyEvent(this);
        }

    }

    public String Symbol

    {
        get { return _symbol; }
    }

    public double Price

    {
        get { return _price; }
    }
}

 

public class Investor

{
    private string _name;

    public Investor(string name)

    {
        this._name = name;
    }

    public void SendData(object obj)

    {
        if (obj is Stock)

        {
            Stock stock = (Stock)obj;

            Console.WriteLine("Notified {0} of {1}'s " + "change to {2:C}", _name, stock.Symbol, stock.Price);
        }

    }

}


 

效果及实现要点

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

2.目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播。观察者自己决定是否需要订阅通知。目标对象对此一无所知。

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

适用性

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

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

3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。

总结

通过Observer模式,把一对多对象之间的通知依赖关系的变得更为松散,大大地提高了程序的可维护性和可扩展性,也很好的符合了开放-封闭原则。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值