Simon lives in Jersey (Channel Islands) and works as an independent consultant, specialising in software architecture, technical leadership and the balance with agility. Simon regularly speaks at international software development conferences and provides consulting/training to software teams at organisations across Europe, ranging from small startups through to global blue chip companies. He is the founder of "Coding the Architecture" (a website about pragmatic, hands-on software architecture) and the author of "Software Architecture for Developers" (an e-book that is being published incrementally through Leanpub). He still likes to write code too, primarily in .NET and Java. Simon is a DZone MVB and is not an employee of DZone and has posted 32 posts at DZone. You can read more from them at their website. View Full User Profile

RE: Clean Architecture

11.28.2011
| 9278 views |
  • submit to reddit
Decoupling application code from technology *is* good, but...

Clean Architecture is a follow-up post by Uncle Bob to much of the recent commentary on Clean Code Episode VII - Architecture, Use Cases, and High Level Design, including my own post called The delivery mechanism is an annoying detail. I'll keep this short because I only want to pick up on a couple of points. Uncle Bob says...

In the weeks since I started talking about the need to clean up our architecture, I’ve noticed a surprising resistance to the idea. Apparently the notion that it’s a good idea to hide the framework, UI, or database from the application code is not universally accepted.


I'm 100% behind the idea of keeping architectures clean and (as far as possible) decoupling the application code from the technology choices. I even mention "Boundary, Controller, Entity" in my The Frustrated Architect talk (video available) as a good way to decouple. I mean, why would you want to start a web server or database just to run some unit tests? That's crazy.

One somewhat dissenting view, written by The Frustrated Architect in his coding {the} architecture blog is here. He shows a picture, which I’ll repeat:

... see picture below ...

The point he’s trying to make is that if the UI and Database are a much larger part of the system than the business rules, then the architecture of the system should be more oriented around those larger elements. Of course I disagree. No matter how large any one part of the system is, the other parts should be decoupled from it.


No, that's not the point I'm trying to make. I'm saying the delivery mechanism is NOT an annoying detail that can be deferred or ignored "right off the end of the world". I'm going to quote myself here from The delivery mechanism is an annoying detail...

That's right, the annoying detail is actually a large chunk of the system and, for me, architecture is about more than just what's contained within "the application". Structure is very important, but what about that tricky stuff like non-functional requirements, the actual delivery mechanism (technologies, frameworks, tools, APIs, etc), infrastructure services (e.g. logging, exception handling, configuration, etc), integration services (internal and external), satisfying any environmental constraints (e.g. operations and support), etc. For me, this is what "architecture" is all about and *that's* "the whole enchilada".


I consider the role of the software architect to be about looking after the big picture and the type of decoupling that Uncle Bob talks about is exactly the sort of architectural principle that I would adopt on my projects. However, in this role as a software architect, I'd be foolish to ignore the other major factors that may cause my project to fail. This includes, but is not limited to, all of the stuff that I quote above (tricky non-functional requirements, etc). A good software architecture is not just about clean code.

The delivery mechanism is an annoying detail

The executive summary

Again, to recap in case I'm not being clear...

  1. Decoupling application code from technology is good and certainly something we should all strive for. The result is code that is easy to unit test, easy to substitute, easy to maintain, easy to change, etc.
  2. Software architecture is about the big picture and application code is only one part of that big picture.
  3. You run the risk of your software project failing if you continually defer significant decisions about the "delivery mechanism" and don't consider how to address your significant non-functional requirements and/or constraints.

To summarise points 2 and 3 ... the delivery mechanism is not an annoying detail. Now, please go back and read Clean Architecture from the "Not Rocket Science" section because there's some really good advice in there. :-)


Source: http://www.codingthearchitecture.com/2011/11/22/re_clean_architecture.html

Published at DZone with permission of Simon Brown, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Sebastian Gozin replied on Mon, 2011/11/28 - 4:55pm

One of you says, defer your decisions up to the last responsible moment and loosely couple your stuff.

The other says, no don't defer your decisions beyond the last responsible moment and loosely couple your stuff.

I think there may unintentionally be something weird going on. It seems seems well intentioned though I fear the latter opinion may backlash into, make decisions before you can make rational, reasonable and responsible decisions and nevermind about coupling. While trying to prevent the opposite.

Fabien Bergeret replied on Tue, 2011/11/29 - 4:03am

The question I'm currently struggling with, concerning the loose coupling, is the following: JPA's favorite way of mapping object is by using annotations in the code of entities. It means that the code of the entities, which is supposed to be clean and independant from ... well, anything, is stuffed with @Version, @Id and @Column annotations. How to cope with both the use of standards (JPA) and loose coupling?

Simon Brown replied on Wed, 2011/11/30 - 5:06pm in response to: Fabien Bergeret

Right ... and while I said "Decoupling application code from technology is good and certainly something we should all strive for", there are times when this isn't practical. Thankfully the coupling that you are referring to is simply though annotations, so you can still write unit tests that don't necessarily require web/application/database servers to be started up. Once your domain objects (for example) start inheriting from framework classes ... well that's a different story.

Simon Brown replied on Wed, 2011/11/30 - 5:38pm in response to: Sebastian Gozin

As I said in the blog entry ... "You run the risk of your software project failing if you continually defer significant decisions about the "delivery mechanism" and don't consider how to address your significant non-functional requirements and/or constraints".

Let me ask some questions; unless you're using a true Model-Driven Architecture approach where you're defining application behaviour in an executable UML syntax and then generating code from your model (the ultimate deferral!)...

  • Why would you defer your choice of the delivery mechanism? (e.g. web vs console app)
  • Why would you defer a decision such as which web server to use? (e.g. most organisations have existing web servers in place, existing licenses, existing operational procedures, existing support knowledge, etc)
  • Why would you defer your choice of ORM, DI framework, etc, etc? (wouldn't you prefer to hire a team that already has experience in your choice of technologies?)

Yes, decoupling application code from technology *allows* you to defer decisions but the point I want to make is that any deferral should be a *conscious decision* and not some "best practice" statement. Decoupling application code from technology isn't the same as deferring decisions and you can still write application code that is decoupled from your technology even if you have chosen that technology rather than deferring it.

As I said in my "The Frustrated Architect" talk at Skills Matter (http://www.codingthearchitecture.com/presentations/skillsmatter2011-the-frustrated-architect/), there are *some* things that shouldn't be deferred and *some* things that can be deferred. If you have no complex non-functional requirements and see all technologies as equal then you really can defer technology decisions forever. If you think that choosing the wrong technology could harm the success of your software project, then perhaps you should put some effort into figuring out what the right choice is early rather than (as Uncle Bob says), "keeping your options open for as long as possible". If you have concerns about making responsible decisions ... well that's when coding early (prototyping, proofs of concept, spikes, stripes, tracers, etc) comes into play.

 

Lund Wolfe replied on Sat, 2011/12/03 - 7:41pm

Certainly you want separation of concerns and decoupling from implementations, like a specific database vendor or webserver vendor and proprietary lockin. Hopefully, you have the confidence to choose a web framework or GUI framework, like Swing, up front, since you are coding to that interface/API.

You should be able to separate out your view and model, regardless of architecture and technology choices. You want as much modularity, swapability, flexibility, parallel development, and skill specialization as you can get in the interest of simplicity. If you go overboard, though, you end up with an over-engineered solution which is not simple or understandable or maintainable.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.