点击这里给我发消息 点击这里给我发消息

javascript 设计模式之——观察者

添加时间:2010-1-5
    相关阅读: 设计 HTML JavaScript 框架 系统 项目

最近正在做的项目中,前台的javascirpt模块之间的交互比较多,就用到了设计模式中的观察者模式。

  在学习和使用观察者模式时,发现观察者模式其实是事件驱动的原型。c#的事件驱动也算是观察者模式的一种变种吧(不知理解是否正确,希望高手指点)。

  javascirpt的extjs框架的时间驱动的原型也是观察者,因此,观察者模式在模块间交互时可以隔离变化,实现高内聚,低耦合。下面是我的代码

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">CodeCodeCode

<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
 </HEAD>
 <SCRIPT LANGUAGE="JavaScript">
 <!--
 //事件对象
 Event=function(name){
  this.name=name;
  this.eventfns=new Array(); 
 }
 //增加事件的监听者
 Event.prototype.AddEventFn=function(fn){
  this.eventfns.push(fn);
 }
 //获取事件的名称
 Event.prototype.GetEventName=function(){
  return this.name;
 }
 //触发事件
 //{data}触发事件时所附带的数据
 Event.prototype.FireEvent=function(data){
  for(var key in this.eventfns){
   this.eventfns[key](data);   
  }  
 }
 //模块基类
 Module=function(id){
  this.id=id;
  this.events=new Array();
  Kernel.AddModule(this);
 }
 //获取模块的Id
 Module.prototype.getModuleId=function(){
  return this.id;
 }
 //注册模块上的事件
 Module.prototype.RegisterEvent=function(eventName){
  e=new Event(eventName);
  this.events.push(e);
 }
 //增加模块的事件监听器
 Module.prototype.AddListener=function(eventName,fn){
  for(var key in this.events){
   if (this.events[key].GetEventName()==eventName)
   {
    this.events[key].AddEventFn(fn);
    return true;
   }
  }
  return false;
 }
 //触发模块上的事件
 Module.prototype.FireEvent=function(eventName,data){
  for(var key in this.events){
   if (this.events[key].GetEventName()==eventName)
   {
    this.events[key].FireEvent(data);
    return true;
   }
  }
  return false;
 }
 //保存模块的全局对象
 Kernel={};
 //模块的集合
 Kernel.Modules=new Array();
 //向系统增加模块
 Kernel.AddModule=function(module){
  Kernel.Modules.push(module);
 }
 //根据id获取模块
 Kernel.GetModule=function(moduleId){
  for(var key in Kernel.Modules){
   if (Kernel.Modules[key].getModuleId()==moduleId)
   {
    return Kernel.Modules[key];
   }
  }
  return null;
 }
 /**
 * 继承
 * @param {} subClass 子类
 * @param {} superClass 父类
 */
 function extend(subClass, superClass) {
  var F=function(){};
  F.prototype=superClass.prototype;
  subClass.prototype=new F();
  subClass.prototype.constructor=subClass;
  subClass.superclass=superClass.prototype;
  if (superClass.prototype.constructor==Object.prototype.constructor){
   superClass.prototype.constructor=superClass;
  }


 }
 //-----------------------------
 //以上是观察者模式的一种实现。
 //下面是简单测试
 //--------------------------------
 //模块A
 ModuleA=function(){
  ModuleA.superclass.constructor.call(this,'modulea');
  //注册模块的aclick事件
  this.RegisterEvent('aclick');
 }
 extend(ModuleA,Module);
 //模块B
 ModuleB=function(){
  ModuleB.superclass.constructor.call(this,'moduleb');
  //增加模块A的监听事件
  module=Kernel.GetModule('modulea');
  if (module!=null)
  {
   module.AddListener('aclick',
     function(data){
      document.getElementById("test").innerHTML=data;
     });     
  }
 }
 extend(ModuleB,Module);
 
 var a=new ModuleA();
 var b=new ModuleB();


 function FireEvent(){
  alert(a.FireEvent("aclick","哈哈,事件触发了"));
 }
 
 //-->
 </SCRIPT>


 <BODY>
 <input type="button" value="模块A触发模块B事件" onclick="FireEvent()">
 <div id="test"></div>
 </BODY>
</HTML>

本文作者:未知
咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册