Now we all know why the layered architecture sucks (link). The layered architecture is [practically] impossible to create as it’s designed. There exists an implicit dependency of the data layer on the business layer; and a transitive dependency of the presentation layer on the data layer. These two dependencies will probably occur in an implementation of a layered architecture, but are not represented, or acknowledged in the traditional design. There is a better option, and we’ll walk through what that is.
In my last blog post, we came up with this diagram describing what the layered architecture actually results in
Here, the arrows represent a dependency. The presentation layer depends on the business layer, etc. How could we improve on this design? Are there any dependencies here that could be broken? The answer is a resounding… probably. First, Does the business logic need to depend on the database? Fortunately here, the answer is ‘no’. We can imagine a system where changes to a database don’t affect the business layer. Off the top of my head, if we were using JPA, then a switch from Jboss to EclipseLink wouldn’t have us modifying methods throughout the business layer. In this example, the choice of database is almost like a deployment detail. Granted this is a cherry-picked case, but it shows it’s possible… so let’s run with it for now. Trust me.
So, because of [let’s say magic] we think the dependency of the business layer on the data layer is broken. Fortunately, we get two birds with one stone here. The presentation layer was only “transitively” dependent on the data layer (see post on why the layered architecture sucks). Breaking one dependency breaks another. Yay.
Here’s the new picture:
Things are looking simpler already. Let’s step it up…
Hypothetically, could we do this?
Could we have two presentation “layers”? let’s say REST and command line. Or printer and screen. It feels like this could happen. I couldn’t imagine a bug fix to one requiring a change in another. Could there be two ways of “presenting” that depended on each other? Would they be separate “layers” or in the same “layer”?
What if we kept going this way?
The diagram is getting a bit stupid now. However, notice that the database and presentation code(s) all depend on the business code and don’t depend on each other. You could probably think of some other type of code that might fit along side these two. It kind of feels like we could put them all in the same “layer”. I don’t know what it’d be called, maybe the “depends on the business logic layer”, or “the stuff on the outskirts layer”. Let’s try it… Here’s a picture.
Curiously enough, by chewing up and fiddling with an architecture we don’t like, we’ve stumbled across one that already exists. This is essentially the Onion architecture, or Clean Architecture. Here’s the diagram for the clean architecture. (source: 8th light blog)
Notice the DB, Web and UI way on the outside. Also notice that dependencies point inwards only. (just like we like it) Here, they’ve got a few extra layers; in the very middle is “Entities” or “Enterprise” code. This is the portion of your code that’s core to what it does, and subsequently is what’s least likely to change on you. The farther we move away from the center, the more our code is about how we choose to do things, and therefore more likely to be the type of code we might modify.
Is this just another architecture that’s great in theory, but not in practice? My code needs to call a database to get information… and just using JPA (like we mentioned earlier), isn’t always an option. How can we call code on that outside layer without knowing about it? I can’t hand control over to code that I don’t know exists. Can I? Well, yes. The workhorse that makes this architecture possible is the Inversion of Control pattern. (And a little bit of dependency injection). I’ll go over Inversion of Control in my next post.