Posts Tagged Architecture
A while ago I posted here about the role of the architect when building lean software. Inspired by posts by Kirk, Hal and Joel, I’d like to build a case for selecting the right tools and frameworks in order to be able to sustain your agility in the long run.
Starting with the opening argument that Hal makes, we’ve all been in projects for long amounts of time, where at one point you start wondering what became of that once beautiful and comprehensible design, or those fast build and test cycles you started out with. As products evolve over time, they all seem to loose a lot of their initial “elegance” up to the point where people seriously start considering starting from scratch “because it’s easier than bolting on new features to the existing product”. Apart from the fact that that is very counter-productive from the point of view of the customer, you’re also throwing away a lot of experience, especially if the original authors of that code are no longer around (which sometimes is stated as a reason to start over). Joel made a case for not starting from scratch and raises some very valid points there.
So, if it’s not smart to start from scratch, and you really want to sustain that agility, how are you going to make that happen? There, going back to one of the points that Kirk makes, a lot depends on your architecture, especially if you look at it from his point of view:
The goal of architecture is to minimize the impact and cost of change. To do this requires we create flexible systems with the ability to adapt and evolve. But with flexibility comes complexity, presenting architects with a paradox. As we design more adaptable systems, the additional complexity reduces their ability to survive. Eventually, the software rots, the architecture crumbles, and the system fails. Therefore, we must find a way to increase adaptability without decreasing survivability.
Combining observations here it becomes increasingly important to stay modular and to really try hard to loosely couple your components because that has tremendous benefits in the long run. Doing that is not easy though, as it requires a lot of thought, and you might need to make some other trade-offs in favor of modularity and loose coupling. However, it is one of the few ways that allow you to make decisions that are always reversible, as ripping out a single component in an environment where there are as little dependencies as possible and where each of these dependencies have small and substitutable interfaces remains as easy as it was when you started the project. In practice it also means that it is worthwhile ensuring that these qualities in the overall architecture do not deteriorate and that you spend enough time making sure they don’t by refactoring and reviewing code as part of the normal development cycle.
When we first started doing Scrum a couple of years ago, there was some discussion about the role and place of the architect in an agile process. Some of the initial literature we read did not mention an architect at all. Building and delivering software in short sprints seemed to encourage a very hands-on approach to software development, trying, building and refactoring in a very iterative way.
However, developing in sprints did not mean that we could all just “dive in” and design as we pleased. On the contrary, by adopting a process where the requirements can change every sprint, it becomes even more important to have some kind of architecture that is just as flexible. In fact, it is the ultimate test for any architecture: a couple of sprints down the road, how easy is it to go in a different direction, to really change core aspects of the system?
Some important lessons we learned here are:
- Build your software out of reusable, loosely coupled components. Components can easily be refactored, rewritten or thrown away with consequences that are easy to oversee.
- In the age of libraries and frameworks, be very selective about using big frameworks, especially if you only use 20% of them. Usually at some point, the added complexity of the other 80% will bite you.
- Have components communicate using service interfaces that are as “small and simple” as possible, and implement them in the simplest way that makes sense. Like with performance optimizations, don’t prematurely optimize until you know something is a problem.
- Prototype the most critical or complex components in your application. This is where the experience of senior engineers and architects can really make a difference.
- Keep things simple. For example, building and deploying an application should be as easy as possible. I’ve seen too many cases where you had to follow a long list of steps to get “something that works”. Besides, in your continuous build, you want to produce working artifacts automatically, on every build.
In the end, it’s the role of the architect in this process to make sure the whole team shares the same technical vision. This can be achieved by working closely with the team (an architect should really also have all the engineering skills to talk with any member of the team and really understand what they’re doing), explaining the important aspects of the decisions that were made. It makes sense to document the architecture and design a wiki, using any means necessary, such as taking photos from whiteboards. Make sure these documents are actively read and maintained by the whole team. One thing you definitely should not do is sit in a room for a couple of months and write “the architecture document” in splendid isolation. That is the best way to ensure it will never be read or used.