I don't have a lot of experience writing libraries and just recently started thinking a lot about structure and patterns.

I wrote a tiny module manager based on the facade and mediator design patterns and very vaguely based on require.js / AMD and libraries using facade+mediator patterns like jQuery.

My goal is not only to decouple but to provide a minimal, self-descriptive mediator function as an entrance point into modules serving as a kind of tutorial.

So if everything works out inspecting a module via console.log(), it only shows the exposed mediator function and hopefully gives the required information needed to use the module without looking up in the documentation most of the time

Here is an example module featuring all structural components:

imports(["module1","module2"],function privateModuleConstructor(moduleOne,moduleTwo){
    var privateVar = "hidden and can only be accessed through the closure";

    return exports(function longDescriptiveMediatorName(){
         var a = arguments,
             l = a.length;
             c = a.callee;
         /* ...exposed part of the facade... */
         if(l===0)                     {return privateMethod()};
         if(typeof a[0] === "string")  {return privateVar+a[0]};
         if(a[0] instanceof Array)     {return privateMethod.apply(c,a[0])}


    function privateMethod(){
        return privateVar.replace(/hidden/,"now revealed");
    function publicMethod(){
        return "exposing methods without mediator increases coupling but is possible"

How intuitive does this feel to you? Even without seeing the exact source of imports and exports, does this give you the information you would need to write a module yourself?

edit: After using the pattern for a month it turned out to be rather tedious most of the time. Some modules just can't be reasonably decoupled this way, so it's far from being the magic formula solution that solves all my problems. But it did work out very well for some modules.

I ended up just not using the mediator function when starting out to write a new module, simply use the module and then pay attention and decouple when I ended up actually using the module in many different places and saw an opportunity to reduce the complexity of my use cases.

  • \$\begingroup\$ Why would you privateMethod.apply(null,a[0]) rather than privateMethod(a[0])? Passing null as a context is pointless, IMO. \$\endgroup\$
    – Johan
    Jun 13, 2014 at 13:47
  • \$\begingroup\$ @Johan There is a big difference between .apply and .call or () \$\endgroup\$
    – pllee
    Jun 13, 2014 at 15:44
  • \$\begingroup\$ Oh sorry haha I'm still a bit new to Javascript. It's a thing I'm currently experimenting with, so it probably is super dorky. Thanks for noticing it, I'm going to read in depth about this topic :) \$\endgroup\$
    – Winchestro
    Jun 13, 2014 at 17:20

1 Answer 1


Odd question,

  • arguments.callee is considered obsolete, it's use will trigger an error in strict mode
  • On top you use moduleOne, but you pass module1 in the array in your exports call
  • You did not provide the source for exports
  • You have both missing & unnecessary semicolons ( jshint.com )
  • This

    var a = arguments,
        l = a.length;
        c = a.callee;

    should be

    var a = arguments,
        l = a.length, //<- Comma here
        c = a.callee;
  • Traditionally the private things go on top, with a return/export at the bottom, still I like your way better

  • I'm assuming your exposed part of the facade is just a show case of what you can do and you will not actually decide which function to call based on parameter count and type.

All in all, I find this introduces complexity while not providing very much in return. Personally, I would hold off on modules until I really need them. And then, use require.js.

  • \$\begingroup\$ Thanks for the detailed feedback! I didn't know about the arguments.callee deprecation. I'm going to edit in my experiences using / tweaking this pattern for a month into the question. \$\endgroup\$
    – Winchestro
    Jul 15, 2014 at 8:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.