The Mediator Design Pattern

The Mediator is a behavioral design pattern in which objects, instead of communicating directly with each other, communicate only through a central message passing object (the Mediator). The Mediator pattern facilitates both loose couple and high cohesion.

Loose Coupling

Coupling measures the degree to which program modules rely on other modulesLoose couplingimplies each component can operate or be tested independently of other components. Tight coupling implies each component "knows" the details or inner workings of other components. The Mediator almost entirely eliminates coupling between participating objects by becoming the only outside point of contact. All a module needs to know is how to broadcast messages through the Mediator — it doesn't matter whether 0, 1, or even 100 other modules act on those messages.

  • What's good about loose coupling? Loose coupling facilitates rapid prototyping by getting rid of code dependencies. Components can broadcast and/or listen for messages without worrying about the rest of the system. Messages can be completely ignored, or handled by any number of other components at once. You can add and remove listening objects without changing anything about how those messages are broadcast. It is typically much easier to add new features to software when its components are loosely coupled.
  • What's bad about loose coupling? By inserting the Mediator between objects, components always communicate indirectly, which may cause a very slight performance hit. Also, due to the very definition of loose coupling, there's no way to tell how the system might react to a message by only looking at the point of broadcast. For some, this may take a shift in thinking. This is actually good, though — If components call each other directly, for example usingmyObject.someFunction(args), then one change in how your program works may cause a ripple effect of changes through several modules. TL;DR: tight coupling causes headaches

High Cohesion

Cohesion is a measure of how focused a piece of code isHigh cohesion implies a component's properties and methods are strongly related, and work toward one or more closely related tasks.Low cohesion implies a component may handle two or more unrelated or dissimilar tasks.

  • What's good about high cohesion? Lower maintenance cost, whether that means money, time, stress, or some combination thereof. Software modifications tend not to affect other parts of the program, which means you can make them in less time and with more confidence. Reading and understanding your code also becomes easier when related tasks are grouped. High cohesion also facilitates code reuse, which again saves time and money. If you need to perform the same task in another application, you know where to go for the solution, and you know unrelated or unnecessary code won't "tag along".
  • What's bad about high cohesion? I could come up with no obvious downsides to high cohesion — if you know any, please leave a comment for the sake of completeness!

The following example was built on ideas presented by Paul Marcotte. I especially like his comparison between the Mediator pattern and the Observer pattern:

"Instead of using the Observer pattern to explicitly set many-to-many listeners and events, Mediator allows you to broadcast events globally across colleagues."— Paul Marcotte

    Mediator = function() {
       
        var debug = function() {
            // console.log or air.trace as desired
        };
       
        var components = {};
       
        var broadcast = function(event, args, source) {
            if (!event) {
                return;
            }
            args = args || [];
            //debug(["Mediator received", event, args].join(' '));
            for (var c in components) {
                if (typeof components[c]["on" + event] == "function") {
                    try {
                        //debug("Mediator calling " + event + " on " + c);
                        source = source || components[c];
                        components[c]["on" + event].apply(source, args);
                    } catch (err) {
                        debug(["Mediator error.", event, args, source, err].join(' '));
                    }
                }
            }
        };
       
        var addComponent = function(name, component, replaceDuplicate) {
            if (name in components) {
                if (replaceDuplicate) {
                    removeComponent(name);
                } else {
                    throw new Error('Mediator name conflict: ' + name);
                }
            }
            components[name] = component;
        };
       
        var removeComponent = function(name) {
            if (name in components) {
                delete components[name];
            }
        };
       
        var getComponent = function(name) {
            return components[name]; // undefined if component has not been added
        };
       
        var contains = function(name) {
            return (name in components);
        };
       
        return {
            name      : "Mediator",
            broadcast : broadcast,
            add       : addComponent,
            rem       : removeComponent,
            get       : getComponent,
            has       : contains
        };
    }();

And here's how to use it:

    Mediator.add('TestObject', function() {
       
        var someNumber = 0; // sample variable
        var someString = 'another sample variable';
       
        return {
            onInitialize: function() {
                // this.name is automatically assigned by the Mediator
                alert(this.name + " initialized.");
            },
            onFakeEvent: function() {
                someNumber++;
                alert("Handled " + someNumber + " times!");
            },
            onSetString: function(str) {
                someString = str;
                alert('Assigned ' + someString);
            }
        }
    }());
    Mediator.broadcast("Initialize");                 // alerts "TestObject initialized"
    Mediator.broadcast('FakeEvent');                  // alerts "Handled 1 times!" (I know, bad grammar)
    Mediator.broadcast('SetString', ['test string']); // alerts "Assigned test string"
    Mediator.broadcast('FakeEvent');                  // alerts "Handled 2 times!"
    Mediator.broadcast('SessionStart');               // this call is safely ignored
    Mediator.broadcast('Translate', ['this is also safely ignored']); http://arguments.callee.info/2009/05/18/javascript-design-patterns--mediator/

JavaScript Design Patterns: Mediator的更多相关文章

  1. Learning JavaScript Design Patterns The Module Pattern

    The Module Pattern Modules Modules are an integral piece of any robust application's architecture an ...

  2. AMD - Learning JavaScript Design Patterns [Book] - O'Reilly

    AMD - Learning JavaScript Design Patterns [Book] - O'Reilly The overall goal for the Asynchronous Mo ...

  3. Learning JavaScript Design Patterns The Observer Pattern

    The Observer Pattern The Observer is a design pattern where an object (known as a subject) maintains ...

  4. Learning JavaScript Design Patterns The Singleton Pattern

    The Singleton Pattern The Singleton pattern is thus known because it restricts instantiation of a cl ...

  5. Javascript Design Patterns - Js Class

    JavaScript is a class-less language, however classes can be simulated using functions. eg: // A car ...

  6. Learning JavaScript Design Patterns The Constructor Pattern

    In classical object-oriented programming languages, a constructor is a special method used to initia ...

  7. javascript design patterns

    http://jsdesignpatterns.com/ http://www.joezimjs.com/tag/design-patterns/ http://codecube.net/#archi ...

  8. [Design Pattern] Mediator Pattern 简单案例

    Meditor Pattern,即调解模式,用一个调解类类处理所有的沟通事件,使得降低多对象之间的沟通难度,属于行为类的设计模式.为了方便理解记忆,我也称其为,沟通模式. 下面是一个调解模式的简单案例 ...

  9. Design Patterns All in One (JavaScript Version)

    Design Patterns All in One (JavaScript Version) JavaScript 设计模式 JavaScript 数据结构 23种设计模式分为 3 大类: 创建型模 ...

随机推荐

  1. 图的邻接表存储表示(C)

    //---------图的邻接表存储表示------- #include<stdio.h> #include<stdlib.h> #define MAX_VERTEXT_NUM ...

  2. (转载)高速ADC的关键指标:量化误差、offset/gain error、DNL、INL、ENOB、分辨率、RMS、SFDR、THD、SINAD、dBFS、TWO-TONE IMD

    (一)一个基本概念 分贝(dB):按照对数定义的一个幅度单位.对于电压值,dB以20log(VA/VB)给出:对于功率值,以10log(PA/PB)给出.dBc是相对于一个载波信号的dB值:dBm是相 ...

  3. 理解KMP

    KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n),KMP匹配算法,可以证明它的时间复杂度为O(m+n).. 一.简单匹配算法 先来看一个 ...

  4. font-size的探究

    整理网上的资料 font字体,用px,em,100%,rem?分什么情况考虑? 我们逐渐意识到,我们用px作为文字大小的单位,已经出现很多问题.最主要是体现在用户不能灵活的控制文字的大小. 对于大多数 ...

  5. s3c2440串口裸板驱动(使用fifo)

    使用fifo的好处有: 1:串口的数据发送的数据量较大时,使用fifo可以大大降低MCU的开销.(有点类似串入并出的cput处理模型,本质上还是串行收发) 2:在某些特殊场合,例如制定较复杂的协议时, ...

  6. MyEclipse2015对Javascript自动提示的终极支持

    2015通过集成Tern.js,进入了JS自动提示的最新时代 先看看具体效果吧:   点击链接会进入:   而tern.js已经支持相当多的框架:   关键这个提示不只是纯粹的js文件,对于jsp等等 ...

  7. HDU5873:Football Games

    题目链接: Football Games 分析: 先将分数排序,然后 设当前队编号为p,设个指针为p+1,然后p>1,每次p-=2,指针右移一位p==1,指针指向的队-=1p==0,从指针开始到 ...

  8. c# 范型Dictionary实用例子

    //定义 public static Dictionary<string, object> dict =new Dictionary<string, object>(); // ...

  9. Test log4net

    protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGloba ...

  10. IE8-模拟script onerror

    利用VBScript 检测,有副作用,慎用! var loadScript = function () { var DOC = document, HEAD = document.getElement ...