JavaScript问题中的中介模式

时间:2011-08-04 19:11:08

标签: javascript oop design-patterns mediator

我正在为我的工作创建一种基于调解器的库。我们创建了大量应用程序,因此我想要一些可以在每个应用程序的基础上轻松获取和修改的内容。我也希望它很容易创建“小部件”(缺少一个更好的术语)并且易于删除它们而不用担心破坏任何东西。我们制作的许多这些应用程序也可由外部开发人员为应用程序制作应用程序或小部件进行扩展。

这就是我遇到调解员模式的方式。我写了一些像这样的东西:

//Extend
Core.extend('widget',function(params){
  alert(params.message);
});

//Load it
Core.load('widget',{message:'Hello World'});

//Remove it
Core.remove('widget');

我有3个问题:

  1. 你应该如何/应该使用JavaScript处理这种模式中的DOM操作?我不希望开发人员在他们的小部件之外搞乱DOM。

  2. 您应该/应该如何处理AJAX请求。你应该做什么吗?您是否应该在库中提供AJAX / JSONP调用(在此示例中为Core)。

  3. 我最大的问题是,你如何与其他小部件进行实际交互?我不想紧张夫妇(显然),但我不知道你如何与另一个小部件互动。例如,假设您有一个文本框,并在提交时将其发送到数据库。另外一个小部件怎么可以称之为“时间轴”小部件,现在提交时,然后用文本框小部件中的文本更新时间轴?

  4. === UPDATE ===

    我最后写了这个:

    http://oscargodson.github.com/Core.js/

1 个答案:

答案 0 :(得分:3)

与小部件交互的小部件:我刚刚在几天前完成了这个。我仔细研究了你实现它的方式,这里有一些额外的想法。

您构建的推送系统与jQuery的DOM事件系统非常相似,可以发送和接收任意事件。我一直在使用该系统开发去耦合小部件然而我发现它非常缺乏因为最终“推”(事件,发出,等等)都是脱离上下文的 - 因为在听众中不知道是否这样甚至在他们想要的事情范围之内,直到他们询问事件。

例如,考虑网页上的每个UI元素是否是系统中的小部件。一页上很容易就会有30多个。如果每个人都要推送“已加载”的消息,则其他29人必须接收它。此外,正如您所提到的,第三方开发人员将为此系统进行开发。然后,它将负担放在他们身上,以过滤掉他们不想接收的信息。

我在最新的小部件通信系统中采用的方法就是我称之为“pubstring”/“substring”的方法(公平地说,我确信其他人在我面前提出了这个想法,并且它的一些很酷的名字)。基本上,每当一个小部件“推”时,该推送就会变成一个字符串,其中包含:领域(上下文),小部件的类型,小部件的特定ID,以及特定的消息。

所以说例如一个ID为45的小部件,输入“tweet-list”,在领域“custom”中推送一条消息“loaded”。然后,pub字符串将呈现为:custom.tweet-list.45.loaded

当订阅被放置时,它们通过哈希表输入,该哈希表可以选择包含4个属性的值(除了我拥有的领域/类型/ id / msg之外,您可以轻松添加更多)。听力就像是:

listen({ realm: 'custom', type: 'whatever' }, f); // (where 'f' is a function)

框架的侦听器部分可以将该哈希表转换为“子字符串”,这将是表示它所代表的过滤器的正则表达式:

custom\.whatever\.[^\.]+\.[^\.]+

该正则表达式作为已编译的正则表达式存储到某个隐藏数组...

__subscriptions.push(new RegExp(subString));

然后每当推送(即发布)某些内容时,框架基本上遍历__subscriptions数组,触发每个存储的子字符串(正则表达式)的.test,并在匹配时执行该子字符串的回调。

使用此系统可以应用无限制的过滤侦听器,并且听众知道他们只接收他们感兴趣的上下文的通知。

示例:

// Listen for all messages by widget ID #99
listen({ id: 99 } ,f);

// Listen for all messages by widgets in realm clientB
listen({ realm: 'clientB' }, f);

// Listen for the data-received push of widgets whose type is tweet-list
listen({ type: 'tweet-list', message: 'data-received' }, f);

因为正则表达式实际上只是一个连接,所以regex也可以包含在过滤器中。

// Listen for any data- message
listen({ message: 'data-[^\.]+' }, f);

这个系统的优点在于你仍然可以保持当前界面“保持简单”并只测试argument[0]的字符串或哈希表。换句话说..

// This
listen('loaded', f);

// Could be equivalent to this on the backend:
listen({ message: 'loaded' }, f);

我知道这很长,但希望它能给你一些想法。