We were thinking about our road map for Kiln today and I got to thinking about the underlying principles, or themes, I want to guide our planning. Coincidentally, when I got off work and was poking around the web I ran across this post on principles and it motivated me to write up what I was thinking about in the meeting.
I think I can summarize my train of thought, my design themes, in three words Stability, Agility and Scalability (SAS for short.) These three themes aren't all there is to software development, but I think they form a useful foundation for leveraging other architectural systems like SOLID or The Twelve Factor App.
I have always been an iterative developer. I like to get something working and then grow it in to a larger product over time. In order for iterating to work, you have to build a solid base and fix problems with each iteration. Thinking back on my work leading the team that built the Designer Framework for TIBCO, we had more time than the teams using the framework on each release. Basically we would get started and then lock down the next version of the framework for the other teams to use. While there were certainly changes along the way, we spent most of our time dealing with one of my OCD-like fixations - killing bugs. I hate having bugs in my queue, and when I am in charge of a group or product, I hate bugs in my product. So we worked really hard to get rid of as many known bugs as possible in Designer. I think it worked, since Designer was still in production a decade later with minimal support. I define stability as having software that doesn't need a lot of operational maintenance, software that just works. Squashing bugs is a big part of that.
But in order to fix bugs, you have to find the bugs. There are a lot of ways to find bugs. I think a good product is probably going to rely on more than one bug finder, I know that the lead QA person for Designer, Ali Ahmed, was invaluable in our process. In addition to great QA resources, automated testing is an important way to both find bugs and to ensure stability. Automated tests provide you with a quick and easy way to know when you break something.
Automated tests provide a sort of wall around a piece of code. For example, if I am building a client-server architecture, automated tests around the server make it safer to change the server, reducing the chance that the client will be affected. Having these tests not only makes the product more stable, it can provide a level of agility.
I define agility in software as the ability to move software in new directions quickly. A new direction might mean adding a feature or it might mean rewriting your entire server to run on a new platform. Agility comes from having a good architecture, a well organized code base, and from having the automated tests I need to make sure I don't break something every time I change something. Agility can also affect the tools I chose. Modern tools that increase my productivity are better than some older tools. Leveraging build tools, continuous integration, and a good bug tracker, like FogBugz, are important aspects of agility.
I think it is easy for developers to think of stability as unchanging. But this isn't true, stability is about building software that works. Agility is a perpendicular priority that I think of as building software that is easy to work on. Some considerations with agility might include how many files you have to touch to add a simple feature, how many technologies a new developer has to learn to work on your product, do you have multiple "versions" of the same code running at the same time? It isn't that any of these things is wrong, but thinking about agility while I develop provides a forcing function for creating simpler, more maintainable and more "iterable" code.
Scalability is a later addition to my principles. I spent a fair bit of my career working on user interface applications, which only have to address a single user. But as I have moved through the TIBCO messaging group and then in to Fog Creek's developer tools group, the concept of scalability has crept in.
Scalability grows out of stability for me. If you want to make a web-based product that can run for years with minimal support you have to be able to scale that product with minimal effort. Great scalability can't depend on code changes, it has to depend on getting additional resources and changing the configuration.
Scalability can also help with agility. By designing software that is independent, and easy to test, you also make it easy to plug in new elements. In other words, by using patterns like loosely-coupled components and encapsulation you make your software more agile (not to be confused with agile software development.)
So those are my themes - Stability, Agility and Scalability. Some of the ways I try to work toward these themes are:
- Fix as many known bugs as possible
- Automate as many useful tests as possible
- Try to write software that is easy to work on
- Work toward loosely coupled components
- Encapsulate code
I think holding those in my head while I architect software helps make my projects better, easier to maintain and more fun to work on.