Methods builders

Overview

Method builders are the magic that powers the components. Thanks to method builders, Archetype can litteraly "code" some part of the program to behave as you expect it to.

Method builders are both simple in the concept, and very powerful tools: they are just functions that are applied to some methods of the components during the component instanciation.

Currently, writing a method builder requires a very good understanding of the JavaScript language itself, and we would like to improve this in further version for not needing a big level so be aware that it may lead to some (probably minor) compatibility breaks.

Be aware too that any method builder is applied to all of the component you build. This is likely to change in a further version of Archetype too.

We're currently moving from the "method builder" to the "facet" concept. The main difference for us is that method builders are global tools for proxying function, whereas facets are "per component" AoP-style method proxies.

A method builder can do whatever it wants on the function it is applied to. They can be used to:

  • Retrieve informations on the component in order to build some new function in it(have a look at the observe method builder).
  • Add static datas to the functions themselves(have a look at the logger method builder).
  • Replace the original function by another one(have a look at the event sender method builder).
  • Register the function in some place(have a look at the event listener method builder).
  • Add a proxy function around the original one(have a look at the scope method builder).

Current method builders

All current method builders can be found in "Archetype/component/facets" :

eventListenerFacet
looks for methods starting with "on" in a component and registers it to listen for a event named by the rest of the method name. "onFoo" will listen to "foo" events.
eventSenderFacet
looks for methods starting with "fire" in a component and replace them with a function that fires an event named by the rest of the method name. "fireFoo" will fire a "foo" event.
logFacet
copies the name from the method and the component itself in the method function itself: as function are object, you can add or set some properties to the function object.
The complete method name is stored in "method.name" which is usually used by javascript interpreter to store the function name if the function isn't anonymous(and when defining component, you usually use anonymous functions definitions). This trick is great as it ensure a better "stacktrace experience" when you have to debug some code using a stacktrace. You can use it from inside your method using the "arguments.callee.name" property.
An array of the different parts of the method name are stored in a property named "method.packageArray"
observeFacet
is planned to be moved as an AbstractComponent method. The observeFacet just replaces a (usually empty) function named "observe" with a predetermined function in order to help unregistering the component from event handlers when the component is destroyed.
scopeFacet
is the first facet we made, and was one of the main reason of the original component development. ScopeFacet sort methods in 2 categories: private or public. In fact those 2 categories aren't very useful if you use a event based communication, but it was a "nice to have" function.
ScopeFacet detects a private function using its "_" prefix, and will copy the function reference to its name without its prefix. So a method called "_foo" is usable both as "_foo" or as "foo" in the code.
For all of the component methods, scopeFacet will ensure "this" will always be "this" by binding the function to the object. This method builder is one of the main reasons of why method builder are applied at instantiation time (we hope to provide "buildtime" facets in a futur revision), because it needs a reference to "this" in order to bind it to the component.

Configuration

Loaded method builders are stored in the "Archetype.defaultMethodBuilders" defined in archetype.conf.js

Archetype.defaultMethodBuilders = [
    "public_private",
	"eventListeners",
	"eventSenders",
	"observe",
    "logger"
];
			
            

Beware, changing the default order may break your application: "public_private"(the "scopeFacet") and any "proxy" method builder probably has to be applied before other method builders.

You can try to make your own method builder by looking at the default one code and add yours at the right plae in this list.