What is a good software architecture in a nutshell?
Yesterday Nils posted a new article on PHP hates me about starting quick and dirty rather than with a full blown architecture (German, here’s what Google translate does from it).
This produced the question: What is a good architecture and why are there apparently two opposing trenches supporting quality on the one side and speed of development on the other side?
After having had enough time to think about this whilst flying to Spain I came to the conclusion that Nils question whether it would be better to start quick and dirty to fail cheap in case the project is a looser or to stick to a clean and solid architecture and spend more time and money.
Does quick always have to be dirty, clean always have to be slow, is dirty always quicker?
There has been a comment that assumes that Facebook would not be online today if they concentrated on the architecture right away. After all stuff like HipHop took so long to develop. But that’s ridiculous! To scale for billions of users could never have been an early requirement! I am sure there will not be a single line of code of the first Facebook version left in todays application. But apparently the old code was well structured enough to be exchanged and extended.
I don’t think that a good architecture and quick and dirty are two sides of the same coin. I rather suspect that the idea of a good architecture is often misunderstood. So what is a good architecture?
- First it has to be pragmatic above all. It has to level with the original requirements and should not bloat the development costs out of proportion.
- The projects goal is to successfully implement the projects requirements and the architectures primary goal is to support the implementation.
You may think of syntax guidelines, naming schemes, doc comments, 100% unit test coverage, 100% funtional test coverage, UML, test driven development, behaviour driven development, single level of abstraction, ideal software metrics and so forth.
A pragmatic approach would tell you: Don’t fix it if it’s not broken!
- Do the developers have problems with each others syntax? No? Don’t concentrate on a syntax guideline then. Not now anyway.
- Do the developers make use of a generated API documentation? No? Never? Then why bother with doc comments?
- Is test driven development the prefered way of developing in your team? No, then don’t force it one them in a new project.
And the list of questions can go on.
My personal best practice when it comes to architecture and software quality is this:
Investigate if there are already existing software components that solve a chunk of your requirements and if they can be easily integrated into your environment. Yes? Then integrate them and benefit from not reinventing the wheel.
Try to identify the different concerns of your requirements and separate their implementations (this can easily be done by following behaviour driven development and domain driven design which are both easily understood and applied as they don’t bring new tools with them). But don’t go in to deep and instead start separating from the top (think classes first, then methods). Benefit early from avoiding side effects when changing parts fo the code (you will).
And that’s all. Really.
Of course this can be extended with all the above mentioned methods, processes and tools but this will do for a low budget start. Reusing existing components will reduce your development time and what’s more it will reduce the complexity of your own development. And Separation of Concerns (this includes an MVC pattern or similar) will help you to reduce the impact of change to any of the concerns.
Even most evil stuff like procedural code can be acceptable if separated by concerns as it can be easily refactored in the future (remember the boyscout rule).
These are my essentials to start a good and pragmatic architecture which is flexible enough to allow for later introduction of other measures. And from my point of view this is far from being quick and dirty.