Composing features at compile time

"Rémy Mouëza" remy.moueza at gmail.com
Sun Nov 24 06:06:22 PST 2013


This looks like a case study for aspect oriented programming: 
several separated concerns that start to intertwine within your 
code; if left unchecked this could result in some messy code.

In Python, I used reflection and "magic" things and have already 
used the spring AOP in Java that is done with some Aspect classes 
and annotation. I suppose that D could bring the best of both 
world with its compile time reflection and UDA.

But if you are in urgent need for a solution, here is a C++ trick 
called "mixin classes", template classes parameterized on their 
base class:

interface IFoo {
     void action ();
}

class Foo : IFoo
{
     this () {}

     void action ()
     {
         // perform action
     }
}

class FooLogging (T : IFoo) : T {
     Logger logger;

     this () {
         logger = new Logger;
     }

     override void action ()
     {
         logger.info("performing action");
         super.action(); // perform action
     }

}

void main () {
     Foo foo;

     static if (logging)
         foo = new FooLogging!Foo;
     else
         foo = new Foo;

     foo.action ();
}

You get separation of concerns: the logging features are in 
FooLogging, overriding the basic behaviour in Foo; you can add a 
FooEvent mixin class to deal with events and so on to deal with 
any concerns you need.

The "weaving" is done in the main() function in my example. You 
could prefer to put a big `static if (logging)` in the FooLogging 
class body and always instanciate foo instances with the full 
chain of mixin classes (foo = new 
FooLogging!(FooEvent!(FooAuthentication!(...!Foo)))), or anything 
else that fits you better.

This works nicely if your "aspect" (Logging, Events...) applies 
on the whole action() method. Otherwise, you'll have to cut 
action() into smaller methods that will have to be decorated in 
the appropriate mixin class(es) (as the Strategy design pattern).

I am eager to know if anybody else has a better (or more concise) 
solution.
I hope this helps.

On Sunday, 24 November 2013 at 13:18:15 UTC, Jacob Carlborg wrote:
> Does anyone know a good way of composing features at compile 
> time? Say I have a struct or class that I want to support 
> different features that are configurable at compile time. One 
> way would be to just pass in a couple of boolean flags and use 
> static-if, like this:
>
> class Foo (bool logging, bool events)
> {
>     static if (logging)
>         Logger logger;
>
>     this ()
>     {
>         static if (logging)
>             logger = new Logger;
>     }
>
>     void action ()
>     {
>         static if (logging)
>             logger.info("performing action");
>         // perform action
>     }
> }
>
> Using this approach I get the feeling that there will quickly 
> become a big nest of static-ifs. Does anyone have any better 
> ideas?



More information about the Digitalmars-d-learn mailing list