My idea behind testing design patterns is basically to assert dynamic pattern integrity (as opposed to static structure of the code).
A few simple ideas were as as follows.
The singleton:
this "profile" would be tied to a test method (metaphor). Behind the scenes JO would basically monitor how many times the constructor for MySingle is called and throw an exception if it was more than once. The "core:" prefix represents a namespace or pattern-testing library.
The profile could be extended too, by providing a getter method that JO could assert will always return the same object.
I am leaning toward using AspectJ or some AOP framework for the more complex profiling. Although it would be nice to have our own system for managing this.
Currently these are some of the patterns I am thinking of:
To analyze a design pattern at runtime JO has to be constantly aware of each of the objects involved in the pattern. Currently, in the assert tests, this is done by inserting bytecode into appropriate places using javassist.
This is an easy(-ish) solution if you know exactly what objects and methods you need to monitor (say, for triggers), but becomes harder if this is not easily known--i.e. where do we inject the JO bytecode hooks?
With aop you can inject bytecode anywhere in very complex ways using queries across a program structure called "pointcuts."
Let's take the singleton pattern as an example:
Definition - A singleton has only one (shared) instance in an application.
We could test this by adding a monitor to each constructor of a class and raise an assert failed if two instances are detected.
On the other hand if you used a factory method (typical case) it is difficult and awkward to place a monitor IN the factory to determine what it is returning.
With an an aspect, however, we can weave a pointcut around all CALLS to the factory method (from the "testee") and test that the same shared instance is returned. This gets messy with javassist (need tons of reflection code, careful recompilation checks yada). But the aspect would look like:
Essentially an AOP framework (even aspectJ) will use a bytecode library like javassist under the hood, but that said, they simplify the work immensely.
This post is a bit long but I thought it would also serve as documentation for how JO runs tests.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Since we have decided to go with using AOP (more specifically using the AspectJ libraries), we should pick some patterns to hack out some design on how to test them....
how about the observer and flyweight from your above mentioned patterns?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
yea flyweight is a good place to start. A flyweight (from GoF) is basically like a singleton but for instance types.
The best example is java.lang.Boolean
Boolean.TRUE is a "singleton" representing state true. similarly FALSE. It is not a straightforward singleton because there are 2 instances of Boolean available in the system.
For the second I would suggest Multiton over Observer-Observable (as that is a bit abstract and requires some thinking out). Multiton is singleton but based upon a key, so very similar to flyweight, but not quite (since many instances may continue to be created). Best example of Multiton is a key-based DB connection pool like c3p0.
Thoughts? Doubts?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So basically with both of them could we basically have each class be registered with the key or differenciating member (we may not even need that even .equals may suffice) and then assert after each constructor is called that there are no other instances equal to that one.
I think i'm missing something here though that makes this a little more tricky though.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We may want to make design-pattern specific elements to allow deviations or design pattern specific options...
<object-profile name="patternSample" metaphor="testPatternSample">
<singleton>
<!-- Allow changes to which method gets an instance -->
<instanceOf>getInstance</instanceOf>
</singleton>
<!-- All classes to assert this pattern on during the specified metaphor -->
<classes> <class>com.wideplay.Singleton</class>
</classes>
</object-profile>
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Actually its probably best that the classes element be a design pattern specific element (if we are to go that way) because all patterns won't have the same relationship to classes which implement it.
<object-profile name="patternSample" metaphor="testPatternSample">
<singleton>
<class>test.Singleton</class>
<!-- Allow changes to which method gets an instance -->
<instanceOf>getInstance</instanceOf>
</singleton>
</object-profile>
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
My idea behind testing design patterns is basically to assert dynamic pattern integrity (as opposed to static structure of the code).
A few simple ideas were as as follows.
The singleton:
<design-pattern>core:singleton</design-pattern>
<class>MySingle</class>
this "profile" would be tied to a test method (metaphor). Behind the scenes JO would basically monitor how many times the constructor for MySingle is called and throw an exception if it was more than once. The "core:" prefix represents a namespace or pattern-testing library.
The profile could be extended too, by providing a getter method that JO could assert will always return the same object.
I am leaning toward using AspectJ or some AOP framework for the more complex profiling. Although it would be nice to have our own system for managing this.
Currently these are some of the patterns I am thinking of:
dependency injection
singleton
flyweight
adapter
observer-observable
abstract factory
Also want to have a system to detect common emerging patterns (like where a pattern SHOULD be used):
<search-pattern>core:constructor-clutter</search-pattern>
<package>...
This will basically search where a constructor can be replaced by a factory method (to decouple implementation decisions).
Anyway thats the gist of it. feel free to post your thoughts.
Could you explain a little more about how using Aspect Oriented Programming will fix into creating the more complex profiles.
Sure ok. Let's take a step back first:
To analyze a design pattern at runtime JO has to be constantly aware of each of the objects involved in the pattern. Currently, in the assert tests, this is done by inserting bytecode into appropriate places using javassist.
This is an easy(-ish) solution if you know exactly what objects and methods you need to monitor (say, for triggers), but becomes harder if this is not easily known--i.e. where do we inject the JO bytecode hooks?
With aop you can inject bytecode anywhere in very complex ways using queries across a program structure called "pointcuts."
Let's take the singleton pattern as an example:
Definition - A singleton has only one (shared) instance in an application.
We could test this by adding a monitor to each constructor of a class and raise an assert failed if two instances are detected.
On the other hand if you used a factory method (typical case) it is difficult and awkward to place a monitor IN the factory to determine what it is returning.
With an an aspect, however, we can weave a pointcut around all CALLS to the factory method (from the "testee") and test that the same shared instance is returned. This gets messy with javassist (need tons of reflection code, careful recompilation checks yada). But the aspect would look like:
pointcut singleton() : call (com.mydomain.Singleton.getInstance());
Essentially an AOP framework (even aspectJ) will use a bytecode library like javassist under the hood, but that said, they simplify the work immensely.
This post is a bit long but I thought it would also serve as documentation for how JO runs tests.
Since we have decided to go with using AOP (more specifically using the AspectJ libraries), we should pick some patterns to hack out some design on how to test them....
how about the observer and flyweight from your above mentioned patterns?
yea flyweight is a good place to start. A flyweight (from GoF) is basically like a singleton but for instance types.
The best example is java.lang.Boolean
Boolean.TRUE is a "singleton" representing state true. similarly FALSE. It is not a straightforward singleton because there are 2 instances of Boolean available in the system.
For the second I would suggest Multiton over Observer-Observable (as that is a bit abstract and requires some thinking out). Multiton is singleton but based upon a key, so very similar to flyweight, but not quite (since many instances may continue to be created). Best example of Multiton is a key-based DB connection pool like c3p0.
Thoughts? Doubts?
Sounds good to me.
So basically with both of them could we basically have each class be registered with the key or differenciating member (we may not even need that even .equals may suffice) and then assert after each constructor is called that there are no other instances equal to that one.
I think i'm missing something here though that makes this a little more tricky though.
It is a little more tricky than this. I'm going to break out the discussion into sperate threads Multiton and Flyweight.
I see the following in the test.objects.xml in the source. I'm guessing its an example of the suggested xml format...
<object-profile name="patternSample" metaphor="testPatternSample">
<design-pattern>singleton</design-pattern>
<classes> <class>com.wideplay.Singleton</class>
</classes>
</object-profile>
We may want to make design-pattern specific elements to allow deviations or design pattern specific options...
<object-profile name="patternSample" metaphor="testPatternSample">
<singleton>
<!-- Allow changes to which method gets an instance -->
<instanceOf>getInstance</instanceOf>
</singleton>
<!-- All classes to assert this pattern on during the specified metaphor -->
<classes> <class>com.wideplay.Singleton</class>
</classes>
</object-profile>
Actually its probably best that the classes element be a design pattern specific element (if we are to go that way) because all patterns won't have the same relationship to classes which implement it.
<object-profile name="patternSample" metaphor="testPatternSample">
<singleton>
<class>test.Singleton</class>
<!-- Allow changes to which method gets an instance -->
<instanceOf>getInstance</instanceOf>
</singleton>
</object-profile>
Yea that's a good suggestion. I think eventually we should standardize those names into schema. So instead of the current
<myProperty>assertion</myProperty>
It can be more spring-framework like:
<property name="myProperty">assertion.</property>
Then we can include specific xml schema for new design pattern packs. example:
<object-profile>
<adv-patterns:multiton/>
<adv-patterns:classes>
<adv-patterns:class name="com.my.Class"/>
...etc.
Anyway will break this out into a new thread.