JavaScript Design Patterns: Mediator

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/
时间: 2024-12-18 06:44:56

JavaScript Design Patterns: Mediator的相关文章

Learning JavaScript Design Patterns -- A book by Addy Osmani

Learning JavaScript Design Patterns A book by Addy Osmani Volume 1.6.2 Tweet Copyright © Addy Osmani 2015. Learning JavaScript Design Patterns is released under a Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 unported license. It

Learning JavaScript Design Patterns The Module Pattern

The Module Pattern Modules Modules are an integral piece of any robust application's architecture and typically help in keeping the units of code for a project both cleanly separated and organized. In JavaScript, there are several options for impleme

Learning JavaScript Design Patterns The Observer Pattern

The Observer Pattern The Observer is a design pattern where an object (known as a subject) maintains a list of objects depending on it (observers), automatically notifying them of any changes to state. When a subject needs to notify observers about s

Learning JavaScript Design Patterns The Singleton Pattern

The Singleton Pattern The Singleton pattern is thus known because it restricts instantiation of a class to a single object. Classically, the Singleton pattern can be implemented by creating a class with a method that creates a new instance of the cla

Learning JavaScript Design Patterns The Constructor Pattern

In classical object-oriented programming languages, a constructor is a special method used to initialize a newly created object once memory has been allocated for it. In JavaScript, as almost everything is an object, we're most often interested in ob

[Design Pattern] Mediator Pattern 简单案例

Meditor Pattern,即调解模式,用一个调解类类处理所有的沟通事件,使得降低多对象之间的沟通难度,属于行为类的设计模式.为了方便理解记忆,我也称其为,沟通模式. 下面是一个调解模式的简单案例. ChatRoom 提供公用发送短信的方法.User 全部通过 ChatRoom 类发送信息进行沟通.MediatorPatternDemo 演示调解模式. 代码实现 ChatRoom 提供发送信息的方法 public class ChatRoom { public static void sho

23中设计模式(Design Patterns)转载

设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周

Design Patterns Tips

模式是在某情境下,针对某问题的某种解决方案.设计模式是解决某些经常重复发生的设计问题的一些通用解决方案. 一.模式简介 1.策略模式:定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户. 2.观察者模式:定义了对象之间的一对多依赖,当一个对象改变时,它的所有依赖者都会收到通知并自动更新. 3.装饰者模式:动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 4.工厂方法模式:定义了一个创建对象的接口,由子类决定要实例化哪个类.工厂

设计模式(Design Patterns)(转)

设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代 码可靠性. 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样.项目中合理的运用 设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我