Net设计模式实例之观察者模式(Observer Pattern)
一、观察者模式简介(brief introduction)
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化的时,会通知所有观察者对象,使他们能够自动更新自己。
二、解决的问题(what to solve)
当一个对象的改变需要同时改变其他对象的时候,而且不知道有多少对象有待改变时,应该考虑使用观察者模式。
观察者模式所做的工作其实就是解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使的各自的变化都不会影响另一边的变化。
三、观察者模式分析(analysis)
1、观察者模式结构
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、程序运行结果
四.观察者实例分析(example)
1、场景
假设有一股票开盘价格16.50元,自从上市以来价格是不断下降,而且以1.00元的速度下降。
在股票降到12.00元时,股民灵动生活买入了股票。
在股票降到8.05元时,股民jane买了股票。
2、观察者实例结构
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、程序运行结果
推荐阅读
-
Java经典设计模式之观察者模式原理与用法详解
-
C#观察者模式(Observer Pattern)实例教程
-
PHP设计模式之工厂模式(Factory Pattern)的讲解
-
C#设计模式之观察者模式实例讲解
-
C#设计模式之单例模式实例讲解
-
C#观察者模式(Observer Pattern)实例教程
-
C#设计模式之Template模板方法模式实现ASP.NET自定义控件 密码强度检测功能
-
C#设计模式之Builder生成器模式解决带老婆配置电脑问题实例
-
C#设计模式之ChainOfResponsibility职责链模式解决真假美猴王问题实例
-
C#设计模式之Observer观察者模式解决牛顿童鞋成绩问题示例