PoorMansMixins Add comment to Wiki View in Wiki Edit Wiki page Printable Version

Icon

In order to prevent confusion with officialy supported mixin mechanisms that may be added to Groovy in the future, I have used the term 'gynamo' instead of 'mixin'. It is in essence trying to provide the same functionality.

Gynamo is a lightweight mechanism for extending classes with discrete packages of functionality similar to mixins in languages like Ruby.

Terms

To make things easier (hopefully) to understand, the following is a definition of terms used:

  • Gynamee - A class that will be or has been Gynamized with a Gynamo
  • Gynamo - A class that extends the gynamo.Gynamo abstract base class and specifies functionality that will be injected into to Gynamees
  • Gynamize - The process of injecting the functionality specified by a Gynamo into a Gynamee

Example

An example Gynamee
An example Gynamo
Gynamization

Hopefully that illustrates the point.

Download

You can also grab the buildable source from the SVN repository.

Gynamo is released under the same license terms as Groovy.

Documentation

All classes in the Gynamo library are in the package "gynamo".

Gynamos can contain fields (which will be public when injected) and methods (which Gynamos define as closures). All methods and properties are attached via ExpandoMetaClass so all the usual rules apply there.

Methods and properties are attached via the '=' operator so any existing methods or properties with a matching name will be overridden. This is something to watch out for.

Writing a Gynamo

A Gynamo is any class that extends the gynamo.Gynamo class. Gynamo inheritance is not supported, all Gynamos must directly extend the Gynamo class.

Methods (as closures) or fields to be injected must be accessible via getters. Groovy makes this too easy by generating getters for any fields that you don't specify the visiblity of.

You can even add fields and methods statically to a class ...

Gynamizing

The Gynamo class defines the static method gynamize which takes a Gynamee class and a Gynamo class and performs the injection.

Or alternatively using categories ...

Pre and Post Gynamize hooks

If your Gynamo needs to do anything before or after Gynamization of a class there are optional hooks for it

Gynamo Properties

Sometimes you want to add bean like properties to a Gynamee. This is a little awkward but you can make it work using the provided GynamoPropertyStorage class. Another caveat is that you have to define the getter and/or setter for each such property. Here is an example ...

GynamoPropertyStorage is pretty simple. It contains a synchronized WeakHashMap. Take a look at the source for details.

You would use the above like so ...

Gynamo dependencies

If you have a gynamo that depends on another Gynamee being injected then you can specify that with annotations ...

The @GynamoDependency annotation takes a single parameter of type Class which must be another Gynamo. The specified Gynamo will be injected automatically *before* this Gynamo gets injected. Therefore, the methods and fields of the dependency are available on the Gynamee at time of Gynamization.

If your Gynamo depends on multiple Gynamos, you can use the @GynamoDependencies annotation to specify a list of Gynamos that need to be injected before.

*Note:* Be careful of circular dependencies. The dependency handling is pretty simple so if you do have a a circular dependency, your code will blow up with a StackOverflowError. If anyone has any suggestions on how this can be improved please let me know.

 

Search

Results of your search request can come from various sources: the Groovy website itself, the JIRA issues, the API documentation, as well as a few other interesting Groovy-related blogs.

  By  -  pages  -  views  - last modified