You can replace “Architecture Documentation” with any kind of artifact used to describe the design or implementation of your application. This can also apply to requirements, but for this article we’ll stick with technical documents. This happens quite a bit in shops that have a heavy waterfall or big design up front process. The architects work feverishly at the beginning of a development effort to think up an application architecture that will meet every expected need for the entire solution for the duration of the project. They will then painstakingly record this technical wonder in various forms of documentation including lots of UML diagrams because if it’s documented in UML, it has to be right. And much like the architect in the second Matrix movie, they believe that their design is “ a work of art, flawless, sublime.”
And most often when you get into the trenches of actually developing the software, ideas that sounded good on paper often fall apart in implementation and have to be modified to varying degrees. And like good little developers we immediately run back to the now out of date documentation and correct it. Right? Of course, and we deliver the updated documentation to Bigfoot on magical unicorns.
So why does this happen?
- Too Much Design Detail Up Front – Unless the application you are building is exactly like that of those you have built many times before with the exact same team, on the exact same infrastructure, with the exact same technology, and you have at your disposal the ability to manipulate the world to be the exact same as when you developed each of those previous applications, your lovely design will most likely have to be modified during implementation. Often we try to mitigate this fact by documenting even more as if the sheer onslaught of technical details will negate this age old truth.
- Concentrating on Building Frameworks and Not Features – As developers we love to solve the world’s problems whether it asked us to or not. The wasteland of shelfware is littered with the bodies of “flavor of the month” frameworks well intended developers created in hopes of alleviating all foreseeable issues in the future. This also tends to make the design more complex (although most who do it argue the opposite), and requires a certain level of documentation up front just so the developers who work on it can get their heads around how to implement and use it.
This can also result in bloated software that is hard for others to maintain. While a solid architecture often leverages industry proven frameworks like Entity Framework, nHibernate, etc., it is important to weigh each framework you adopt (or write yourself) with the justification of the cost it will incur. We must also look at many of the non-technical implications that can have a large part in the decision like the level of expertise of the people implementing and supporting the application.
Here are some practices and principles I think help:
- Emergent Design – Some think Agile prescribes no design and just slinging code from the start of a project. This is a common misconception. The practice of emergent design is more about designing at a high level initially to clarify the big technical questions, but using tests and developing in iterations to validate design choices as you make them. It is a counter to the so called “ivory tower” architects who stop writing production code and work in more theoretical matters. There are times when this type of work is very much warranted but some detailed specs along with a reference application cannot be deemed as technical gospel until it is proven with production ready implementations. How much design you do up front and how much you allow to evolve along the way is a very contextual decision that should be evaluated for each project.
- Design as a Team – When you design the application as a team, then there is less need to document up front since everyone will be on the same page. It also tends to ensure developers stick to the architecture and design approaches, since they had a hand in crafting them. Another benefit is that junior developers are exposed to elements of the solution and the process for creating it that they might not have had a chance to experience if the application is designed only by the senior team members and then handed to them to implement later.
- The YAGNI Principle – This stands for “You Ain’t Gonna Need It” (I’m southern so we use ain’t instead of aren’t) which is a mantra used by Agile programmers to resist the urge to gold plate software. The more bells and whistles we try to add, the more moving parts it adds and the more points of possible failure we add. I have definitely seen this taken way too literally but stopping and really thinking about whether some extra technical detail is truly needed to meet the business need is always a good practice. The more well known and less controversial version of this is KISS (keep it simple stupid).
- Self Documenting Code – Agile does not mean you do not document. If someone tells you that, then you have my permission to punch them in the ear. Read the Agile Manifesto and you will see it says comprehensive documentation. So there is a certain level of up front design and documentation, but treat that documentation as perishable the second you implement it in code. Once the code is written then the “Code is the truth.” Writing the code in a way that its intent is obvious, even to those not extremely technical, is a great way to preserve the truth of the design. Aside form the code, there are many applications out there that can pull information out of the code into more formal documentation and diagrams so that the intent can be expressed outside of code such as nDoc, Visual Studio 2010’s Architecture Explorer features, and many more.
- A Side Note on Code Comments – I have attended quite a few sessions/presentations over the years that say comments are evil. Well you can shut your cake holes because I like comments. I am not talking about silly, obvious comments like this:
//Declare new Customer.
Customer newCustomer = new Customer();
I am talking about things like XML comments in C# for all public members of a class, and sparingly used comments that sometimes explain why something was implemented the way it was. I also follow the practice of using comments as the stubs for the code I am about to write (something I picked up years ago from Code Complete), but I normally replace those comments with the actual code.
But do understand that when I say “self documenting code”, that does not refer to comments, but rather the formatting and naming of those code structures. If I have to read your comments to understand the intent of your code then I do take issue with that.
- A Side Note on Code Comments – I have attended quite a few sessions/presentations over the years that say comments are evil. Well you can shut your cake holes because I like comments. I am not talking about silly, obvious comments like this:
Ditto!