Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
research:software:reflex:documentation:singleton_aspect [2007/07/29 23:32] – created adminresearch:software:reflex:documentation:singleton_aspect [2007/08/24 18:41] (current) rtoledo
Line 1: Line 1:
 +====== Singleton Aspect ======
  
 +In this section we will transform our application to avoid multiple instances of the Fibonacci class to be created (I bet that you have been thinking we should had used the singleton pattern from the beginning...).
 +
 +This example is very useful as it shows how we can abstract of the application the fact we are using the singleton pattern.
 +
 +In this case, we want to intercept the calls to new Fibonacci and return a unique previously-created (if not exist, we will create one) instance. To do so, first we have to define a hookset that matches the constructor calls:
 +<code java>
 +Hookset theHookset = new PrimitiveHookset(
 +        Instantiation.class,
 +        new NameCS("reflex.examples.fibonacci.app.Fibonacci"),
 +        new InstantiationOfOS("reflex.examples.fibonacci.app.Fibonacci")
 +);
 +</code>
 +
 +Here we use a new kind of operation: instantiation. The instantiation operation matches all statements using the ''new'' keyword. In our case we are interested in instantiations occurring in the Fibonacci class (''new NameCS("reflex.examples.fibonacci.app.Fibonacci")''), instantiations that must be of Fibonacci objects (''new InstantiationOfOS("reflex.examples.fibonacci.app.Fibonacci")'').
 +
 +The declaration of the metaobject definition follows:
 +<code java>
 +MODefinition theMO = new MODefinition.SharedMO(new SingletonHandler());
 +</code>
 +
 +Here we use the ''SingletonHandler'' class, which is in charge of avoiding multiple instance creation. The class definition is:
 +<code java>
 +public static class SingletonHandler {
 +
 +    private Fibonacci itsInstance = null;
 +
 +    public Object ensureSingleton(IExecutionPointClosure aClosure){
 +        if (itsInstance == null){
 +            itsInstance = (Fibonacci) aClosure.proceed();
 +        }
 +
 +        return itsInstance;
 +    }
 +}
 +</code>
 +
 +As you can see, the ''SingletonHandler'' class has only one method: ''ensureSingleton''. This method does a check if the field ''itsInstance'' is ''null'' (it is ''null'' when the method is called the first time): if it does, the variable is initialized with the result of calling ''proceed'' in the closure object. This closure object is a self-contained unit that is able to invoke the original operation (in our case the ''new Fibonacci()'' constructor call). Finally, the instance field is returned. This code ensures that only one ''Fibonacci'' instance will exist.
 +
 +(You can find more information about this closure object [[A Brief Introduction to Around Metaobjects|here]]).
 +
 +Finally, the code of the definition and configuration of the behavioral link is:
 +<code java>
 +BLink theLink = Links.get(theHookset, theMO);
 +theLink.setControl(Control.AROUND);
 +theLink.setCall(Control.AROUND,
 +                SingletonHandler.class.getName(),
 +                "ensureSingleton",
 +                Parameter.CLOSURE);
 +</code>
 +
 +In the code above we set the control of the link as ''AROUND'', meaning that it will replace the original operation. Then we specified that the method ''ensureSingleton'' should be called with one unique parameter: ''Parameter.CLOSURE'', this is a ready-to-use parameter that forces Reflex to generate the infrastructure necessary to allow the invocation of the original operation. Note that if you do not specify this parameter, you will not be able to invoke the original operation.
 +
 +The complete code of the link provider that defines and configures this link is [[http://reflex.dcc.uchile.cl/svn/base/trunk/src/reflex/examples/tutorial/SingletonAspect.java|here]]. The command to run this example is:
 +<code>
 +Windows
 +    %java -classpath 
 +            "lib\javassist.jar;build\reflex-core.jar;build\reflex-examples.jar"
 +            reflex.examples.tutorial.SingletonAspect
 +
 +Linux
 +    %java -classpath
 +            "lib/javassist.jar:build/reflex-core.jar:build/reflex-examples.jar"
 +            reflex.examples.tutorial.SingletonAspect
 +</code>
 +
 +The output should be the same as executing the Fibonacci class without the aspect. You can verify the that the aspect is working adding a ''System.out.println(...)'' line to the Fibonacci class constructor:
 +<code java>
 +public Fibonacci(){
 +    System.out.println("----- Fibonacci Constructor -----");
 +}
 +</code>
 +This line should be printed once.