最近正在做的项目中,前台的javascirpt模块之间的交互比较多,就用到了设计模式中的观察者模式。
在学习和使用观察者模式时,发现观察者模式其实是事件驱动的原型。c#的事件驱动也算是观察者模式的一种变种吧(不知理解是否正确,希望高手指点)。
javascirpt的extjs框架的时间驱动的原型也是观察者,因此,观察者模式在模块间交互时可以隔离变化,实现高内聚,低耦合。下面是我的代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<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>
希望同大家交流javascirpt开发经验.