欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Net设计模式实例之观察者模式(Observer Pattern)

程序员文章站 2022-11-20 15:23:56
一、观察者模式简介(brief introduction) 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化的时,会通知所有观察者对象,使他们...

一、观察者模式简介(brief introduction)

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

二、解决的问题(what to solve)

当一个对象的改变需要同时改变其他对象的时候,而且不知道有多少对象有待改变时,应该考虑使用观察者模式。

观察者模式所做的工作其实就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使的各自的变化都不会影响另一边的变化。

三、观察者模式分析(analysis)

1、观察者模式结构

Net设计模式实例之观察者模式(Observer Pattern)

subject类:它把所有对观察者对象的引用保存在一个聚集里面,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。

public void notify()

{

    foreach(observer o in observers)

    {

          o.update();

    }

concretesubject类: 具体的主题,将有关状态存入具体观察者对象,在具体主题的内部状态改变时,给所有登记国的观察者发出通知。

observer类:抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己

concreteobserver:具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调

2、源代码

1、subject类,主题或者抽象通知者

public abstract class subject

{
	private ilist < observer > observers = new list < observer > ();

	/*
	 * / <summary>
	 * / 添加观察者
	 * / </summary>
	 * / <param name="observer">观察者</param>
	 */
	public void attach( observer observer )

	{
		observers.add( observer );
	}


	/*
	 * / <summary>
	 * / 移除观察者
	 * / </summary>
	 * / <param name="observer">观察者</param>
	 */
	public void detach( observer observer )

	{
		observers.remove( observer );
	}


	/*
	 * / <summary>
	 * / 通知观察者
	 * / </summary>
	 */
	public void notify()

	{
		foreach ( observer o in observers )

		{
			o.update();
		}
	}
}

2、concretesubject类,具体主题或者具体通知者

public class concretesubject : subject

{
	private string _subjectstate;


	/* / <summary> */

	/* / 具体被观察者状态 */

	/* / </summary> */

	public string subjectstate

	{
		get { return(_subjectstate); }

		set { _subjectstate = value; }
	}
}

3、observer抽象观察者,为所有的具体观察者定义一个接口

public abstract class observer

{
    public abstract void update();
}

4、concreteobserver具体观察者

/// <summary>
/// 具体观察者,实现抽象观察者角色所要求的更新接口
/// 以便使本身的状态与主题的状态相协调
/// </summary>
public class concreteobserver: observer

{

    private string name;

    private string observerstate;

    private concretesubject subject;

    public concretesubject subject

    {

        get {
            return subject;
        }

        set {
            subject = value;
        }

    }

    public concreteobserver(concretesubject subject, string name)

    {

        this.subject = subject;

        this.name = name;

    }

    public override void update()

    {

        observerstate = subject.subjectstate;

        console.writeline("观察者{0}的新状态是{1}", name, observerstate);

    }

}

5、客户端代码

static void main(string[] args)

{

    concretesubject cs = new concretesubject();

    cs.attach(new concreteobserver(cs, "james"));

    cs.attach(new concreteobserver(cs, "jane"));

    cs.subjectstate = "ok";

    cs.notify();

    console.read();

}

3、程序运行结果

Net设计模式实例之观察者模式(Observer Pattern)

四.观察者实例分析(example)

1、场景

假设有一股票开盘价格16.50元,自从上市以来价格是不断下降,而且以1.00元的速度下降。

在股票降到12.00元时,股民灵动生活买入了股票。

在股票降到8.05元时,股民jane买了股票。

2、观察者实例结构

Net设计模式实例之观察者模式(Observer Pattern)

stock类,抽象通知者

定义了委托pricechangedhandler ,调用了事件参数stockdetailsargs 。

声明了事件pricechanged.

股票在下跌的过程中调用方法onpricechanged ,通过此方法触发事件pricechanged 。

attachevent 方法用来添加观察者到对象。

stockdetailargs类,事件参数继承于eventargs类,有树形currentprice用来专递价格数据

接口iobserver和具体观察者observer类:

stoc_pricechanged方法:当股票在以1.00元降价的过程中调用此方法。当价格降到符合购买者价格,而且股票没有被其他人购买的情况时,执行购买行为。

开盘价格:16.50

收盘价格:5.50

当价格降到12.00时,观察者灵动生活买入此股票

当价格降到8.05时,观察者jane买入此股票

3、代码

1、stock股票类

public class stock

{

    private double _openprice;

    private double _closeprice;

    public delegate void pricechangedhandler(object sender, stockdetailargse);

    public event pricechangedhandler pricechanged;

    public double openprice

    {

        get {
            return _openprice;
        }

        set {
            _openprice = value;
        }

    }

    public double closeprice

    {

        get {
            return _closeprice;
        }

        set {
            _closeprice = value;
        }

    }

    public void starttrading()

    {

        double current;

        //current price decrements by $1.00 as the stock is traded  
        current = openprice;

        while (current > closeprice)

        {

            //stock is falling in increments of $1.00  
            current = current - 1.00;

            //call the method to raise the event  
            onpricechanged(current);

            //simulate a delay of 2000ms between market price updates  
            system.threading.thread.sleep(2000);

        }

    }

    protected void onpricechanged(double currentmarketprice)

    {

        //any handlers attached to this event?
        if (pricechanged != null)

        {

            stockdetailargs args = new stockdetailargs();

            args.currentprice = currentmarketprice;

            console.writeline("当前股票价格是:" + args.currentprice.tostring());

            ////raise the event
            pricechanged(this, args);

        }

    }

    /// <summary>
    /// 添加观察者
    /// </summary>
    /// <param name="observer">观察者</param>
    public void attachevent(iobserver observer)

    {

        pricechanged += newpricechangedhandler(observer.stoc_pricechanged);

    }

}

2、事件参数stockdetailargs

public class stockdetailargs: eventargs

{

    private double _currentprice;

    public double currentprice

    {

        get {
            return _currentprice;
        }

        set {
            _currentprice = value;
        }

    }

}

3、观察者接口iobserver

public interface iobserver

{

    void stoc_pricechanged(object sender, stockdetailargs e);

}

4、具体观察者observer

public class observer : iobserver

{

    private string _investorname;

    private double _buyprice;

    private stock _stoc;

    private bool _hasboughtstock = false;

 

    public string investorname

    {

        get { return _investorname; }

        set { _investorname = value; }

    }

    public double buyprice

    {

        get { return _buyprice; }

        set { _buyprice = value; }

    }

    public stock stoc

    {

        get { return _stoc; }

        set { _stoc = value; }

    }

 

    public observer(string investorname, double buyprice)

    {

        this.investorname = investorname;

        this.buyprice = buyprice;

    }

 

    public void stoc_pricechanged(object sender, stockdetailargs e)

    {

        if (e.currentprice <= buyprice && _hasboughtstock == false)

        {

            console.writeline(string.format("{0}在价格price ={1}时买进了股票。",investorname,e.currentprice));

            _hasboughtstock = true;

        }

    }

}

5、客户端代码

static void main(string[] args)

{

    stock stock = new stock();

    stock.openprice = 16.50;

    stock.closeprice = 5.50;

 

    observer james = new observer("灵动生活", 12.00);

    observer jane = new observer("jane",8.05);

    stock.attachevent(james);

    stock.attachevent(jane);

    stock.starttrading();

    console.read();

}

4、程序运行结果

Net设计模式实例之观察者模式(Observer Pattern)