Skip to content
Henrik Vendelbo edited this page Apr 30, 2014 · 9 revisions

A resolver is a function that represents a value. If you call the function it will return the current value. If you call the set method on the function it will change the value.

Resolver constructs a resolver. Call it with the expression you want to track.

A generator is a function that makes instances of a constructor function. You call it without a new keyword. The generator can be configured to pass different parameters and/or always return the same instance.

Generator gives you the generator for a constructor. Call it with the constructor function.

An enhanced page is an HTML document with Document Resolver. It keeps track of resource dependencies and backend connectivity. It gradually enhances elements on the page depending on the role as resources become available.

Basic Use

    var Rectangle = Resolver()("shapes.Rectangle");
    var fivefive = Rectangle(5,5);

This will find the generator for a Rectangle constructor previously defined. The generator will call new to make an object that is instanceof the Rectangle constructor. It then initialises properties with initial value and calls the constructor and base constructors.

If you want to specify a common base class and make the concrete class configurable, you need to get a generator variant by.

    var Shape = Resolver()("shapes.Shape");
    var Rectangle = Shape.variant("Rectangle");
    var fivefive = Rectangle(5,5);

To declare the Rectangle and Shape constructors you would do something like

    function Shape() {}
    Resolver().set("shapes.Shape", Generator(Shape));

    function Rectangle() {}
    Resolver().set("shapes.Rectangle", Generator(Rectangle,Shape));  # needed for resolving the concrete constructor
    Generator(Shape).variant("Rectangle",Generator(Rectangle));  # needed for resolving the Rectangle variant of Shape

Why?

The simplest way of sharing information in a JavaScript application is to create a global object. This creates the problem of picking a name for your global variable that others won't reuse by mistake. For more have a look at Namespaces and Globals.

A common pattern is to reuse a previous object or create a new one if it wasn't used before. Constructing Objects with Generators subtly moved the decision of whether to create a new instance from the caller to a middleman. You go from new Rectange(5,5) to Generator(Rectangle)(5,5). Restricting Object Generation allows you to use previously constructed instances rather than creating a new.

When you make an application using typical Java paradigms you will quickly be adding singleton classes. And you will just as quickly see why many people say that "singletons are evil". The problem with singletons is not the concept of sharing a single instance among dependents, rather it is the way the single instance is enforced and the resolution of it. In languages like Java solutions exist under the term Dependency Injection. Since JavaScript is a very different language, it can be done in a fairly simple way using Restricting Object Generation and Generator Argument Injection.

You commonly want to make a particular variant of something. So you know that you want a shape, and the design might say that it is supposed to be a rectangle, but that might be configurable or persisted in a design document. So you want a concrete instance of a shape constructor. The simple solution is Generating a Variant. Occasionally you don't want to a particular variant, but rather use the default one, and allow configurations to determine which constructor to use. [Generating a Default Variant](Generating a Variant).

Essential JavaScript

Solves,

  • Initialise generated object with arguments
  • [Using a specialised object only knowing the base constructor](Generating a Variant).
  • [Using a concrete variant of a base constructor without knowing which](Generating a Variant).
  • [Generating an object not knowing that it is a singleton](Restricting Object Generation).
  • [Non-Global-Object and Private namespaces](Namespaces and Globals)