Thursday, July 03, 2008

The Onion Model

Whenever people ask me how to systematically create an architecture, I present them my Onion Model.
 
If you like to sow onionan onion, you need some preparation. It is important to take care of the right environment and also to think about the requirements an onion needs to grow and what risks you might encounter. From a business perspective, you should also consider what type of onion you like to harvest, but that's a different story.

The inner core of the onion will be the domain model including all core components, their relationships and interactions.

For the next layers you will need a prioritized list of strategic requirements. These requirements influence systemic architecture decisions. For example, reliability, availability, or security. All of them represent operational requirements that result in specific infrastructures. If performance is the most important operational requirement, you will build a performance layer around the domain logic core. With other words, the domain logic will be embedded into the performance infrastructure. Then you turn to the second most important operational requirement. If security is the number two requirement, your existing onion that consist of the functional core embedded to an performance infrastructure will get wrapped by a security layer. This continues until your architecture is stable.

At the end you need to address tactical issues such as flexibility or maintainability. These will become the outer layers of the onion. For some of them, you will need open up your strategic architecture, for instance, by providing hooks.

Eventually, you'll get an "onion" which was designed with a functional core in mind. All important requirements had an higher impact on the onion than the less important ones which was ensured by priorization of onion layers.

4 comments:

Michael Hüttermann said...

That's a great approach and metaphor. Actually I wrote about a very similar metaphor two years ago while writing on my German Wikipedia article "Anti-Pattern". Actually my "onion anti-pattern" has a differnt context of course: if a developer extends code he did not write (and knows so good) he often places another onion slice around the existing solution. He is afraid, not touching or modifying the underlying code at all. Often no kind of tests do exist so working on existing code is very dangerous. Of course your "onion pattern" is much better and desirable. ;-)

Joshua Ramirez said...

This sounds like a great way to look at architecture documentation as well.

John Page said...

Could you go into more detail on the question of how you build a performance layer around the domain logic core? In my mind, performance is at the forefront of my concerns as I work on each and every line of code. How could I NOT be concerned with performance as I write the "domain logic core"? The notion of a performance layer makes me think perhaps of a caching layer. For example a wrapper around a DAO that caches the most frequently requested data. Is this what you intended?

Thanks.

Michael said...

Regarding Joshua's question: this is where one of the weaknesses of metaphors shine through. Adding a layer does not mean, the previous architecture remains unchanged. In our case, let's suppose we've designed the core domain model and now performance is considered. It is not bout performance in general but about a concrete performance scenario such as "when user presses button, next page appears within 2 seconds". Now, we need to think about possible design tactics that help with the performance scenario such as concurrency, caching, etc. When we add the infrastructure for this scenario two things might happen. Firstly, we might add additional components such as a cache. But secondly adding the performance layer might also imply touching existing components, even those from the core domain model, e.g., for providing a thread pool. Thus, adding a layer can also be intrusive.