Some things seems to be way ahead of its time and are completely ignored. IMHO Multidimensional SoC seems to be one of this cases. Before diving into it, let me give you some context.
Back in 2002 (or 03?) I was in a very challenging project team, working with Java/j2ee. Our client at the time, a big insurance company knew exactly what they wanted, but not exactly how to achieve it. Fundamentally the app need to quote and process insurance premiums. There were three channels: web site, branches and partners. Each channel could interfere in different ways on the workflow of the insurance processing and the actual calculation operation – which was big.
Some of the requirements were ludicrous, but real. Things like: we don’t do motorcycle insurance. But any director’s children can have insurance for their motorcycle. Can you believe it?
The obvious solution suggested was to parametrize everything. On each deploy package (one for web, CDs for branches, CDs for partners) we would tweak the configuration, and that would affect the workflow and calculation. Didn’t take long to prove that it wouldn’t work. Back to research…
Someone suggested AOP. Remember, that was back in 02/03. We had aspectj – and others – but they were on their early stages. The experiments demonstrated that, as long as we put the right extensibility points, we could use AOP to produce a proper package to the right channel. It wasn’t that better compared to parametrization, but still…
It was then that I bumped into Hyper/J.
Hyper/J (or Hyperspaces) brings some interesting concepts. It states that each concern of your app (or in the most basic level, your class) is a dimension. You can compose several dimensions and have a final product.
This is extremely powerful.
Imagine that you have an app up and running, and at some point it becomes a requirement to have a set a classes supporting custom serialization. All you need to do is start a new dimension made of abstract classes matching the namespace/name of the target classes, that would implement that support. You can introduce new methods, fields, implement interfaces.
Later, for some reason you’d want xml serialization. Another dimension and you’re set.
All of that keeping your core code untangled of these new concerns.
Porting to our scenario at the time
- We would concentrate effort into building the core of our app. The generic workflow, the default calculation. By breaking the wf and calculation into several methods, we enabled the extension points
- Each new concern that affect any aspect is a new dimension. e.g. web_flavor.
- We compile and assembly the core plus each dimension required for each channel package
Benefits: Complete separation of concerns that would allow the app to evolve with no friction; simple to test assembled package; parallelization of work.
Hyper/J worked in byte-code level. You would normally compile the core and each dimension individually, and run it to compose the final package.
For some reason, though, Hyper/J seems to be dead. It wasn’t popular even when it was very active. Shame. An overview page on alphaworks says it has evolved to another project: Concern Manipulation Environment. CME seems to go more into the AOP concepts, whilst chasing the same goal. Haven’t used it, though, so no opinions.
I’m quite happy to see that Fabian and Stefan are going in this exact direction with the re:motion project, which seems to use Castle DynamicProxy, so the composition happens in runtime. I’ve been thinking into support something like this natively on Windsor 2.0 as well, albeit I believe it’s easier to manage composition in development time.
Before someone jump in and say “you can do the same thing with partial classes” think again. You can’t. You can’t create a separated assembly with MyApp.CustomizationsForMyGoldClient made of partials. Conceptually it solves a different problem.