设计模式初探之观察者模式

 在大多数情况下,业务逻辑层执行完表示层的命令后需要向表示层反馈信息。在我之前的《使用接口封装变化》提到的网络用户管理模块中便是使用观察者模式的一个恰当之处,类功能如下图所示。http://blog.csdn.net/kecp/archive/2009/09/29/4613618.aspx

 

 

 通常软件的多个界面可能对当前登录用户的信息感兴趣,比如说当前登录状态、用户名和经验值等基本用户信息。甚至在业务逻辑层的其它部分也可能对它感兴趣,比如说聊天模块或写日记模块需要知道当前登录用状态及用户信息。对于这问题我们应该怎么办呢,让每个其它模块都拥有用户管理模块接口的一个实例?你很快就会发现变得头烦。而且因为对这个接口的调用结果可能不是马上返回的,比如网络登录连接需要一定时间并可能超时。调用者要不就阻塞要不就不停地查询,效率非常低下。那么登录成功后该由谁来通知其它对这一事件感兴趣的模块呢?如果由调用者的话,那么整个程序实现后就很杂乱而且造成不必要的强耦合。嗯,那就只有使用被调用者来进行通知了。

被调用者相当于一个被观察者,而对它感兴趣的其它模块相当于观察者。只有被观察者自己清楚自身发生了什么改变,只有它才能通知其它人关于自身的一个事件。而观察者通常对它的某一个事件感兴趣,它们希望在产生这个事件的时候能接收到通知,比如主界面、聊天模块和日记模块希望收到登录和注销事件。它们之间的接口是事件,被观察者不需要知道对它感兴趣的具体对象是什么,即登录模块类不需要知道聊天类和日记类是什么,聊天类和日记类只需向登录类注册监听自己感兴趣的事件便可。这便是观察者模式。下面我们看观察者模式怎样帮助我们来解决这一麻烦的问题。

首先我们将NetUserOP设置为被观察者,而主界面MainUI注册为它的观察者,我们只描述它的登录事件,代码如下:

//业务数据(被观察对象)

public class NetUserOP: ObservableImpl {

//被观察者中的数据

bool hasLogin;

User _user;

public void  login(user) {

  if( netLogin(user) == true ) //这里可能会发生阻塞

 {  hasLogin =true;

      _user=user;

      base.NotifyObservers(_user);//将登录成功的消息通知观察者

       }

}

}

 

//用户界面(观察者)

public class MainUI : IObserver {

public void Notify(object anObject){

Console.WriteLine("The user  is:" + ((User) anObject). user.name );

}

}

//实际调用的过程

public class MainClass{

public static void Main() {

//创建观察者和被观察者

MainUI ui = new MainUI ();

NetUserOP op = new NetUserOP ();

//在被观察对象中注册观察者

op.Register(ui);

//改变被观察对象中的数据,这时被观察者会通知观察者

op.login( new User( account,password) );

//注销观察者,停止观察

stock.UnRegister(stockDisplay);

}

}

上面我们把网络登录类设置为了被观察者,当登录成功的时候,它把登录用户类User对象通知给对它感兴趣的观察者,这时观察者用户界面类将会输出该登录用户的名字。而相应的如果有实现了IObserver接口的子界面对象childUI以及聊天类对象talk,它们仅需要添加以下代码并可获得用户的登录事件通知:

op.Register( childUI );  op.Register( talk );

 至此,我们解决了业务逻辑层向表示层进行反馈的问题。观察者模式频繁用于GUI应用程序中,使得层间接口清晰,上下层相互独立。代码分层本质上就是对责任分层,观察者模式将责任正确的分配到了对应的对象中,这样便于代码的维护以及扩展。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值