During the twenty years I’ve spent in the software industry, my primary interest has been the design of software. What makes a good design? How do we pass on good designs? What processes encourage good designs? I concentrate on Enterprise Applications: which usually involve large amounts of data that humans need to understand and manipulate.
I’ve concluded that the majority of the time you need to take an evolutionary approach to software design, which explains my involvement in the agile community. I’ve also concluded that patterns are one of the most effective ways to organize and communicate ideas about design.
Evolutionary Architecture and Design
Perhaps the biggest shift in my thinking during my career has been towards an evolutionary approach to architecture and design. When I was first taught about software design, it was as an activity separated from programming that should be completed before programming began. Now I see it as an activity that is intertwined with programming. I wrote about this shift in detail for Is Design Dead - one of my most popular web articles. You can find more articles and bliki entries under the evolutionary design tag.
My colleague Neal Ford is a frequent writer and speaker who shares many of my interests and opinions (and an excellent source of ideas for me to clip). In 2009-10 he wrote a series of fifteen articles for IBM developerWorks which dug deeper into the question of evolutionary architecture and design. His topics include Test Driven Development, leveraging reusable code, refactoring towards design and Domain-Specific Languages.
Following on from this, he’s also recorded a video workshop on Agile Engineering Practices for O’Reilly that’s available on safari books online. These cover much of the topics that make evolutionary design possible, including Test-Driven Design, automation, and testing strategies.
In the early 00’s, I was often buttonholed by various people, particularly Paul Hammant, who told me about their use of inversion of control. Many of these conversations left me more puzzled than anything else, but eventually I spent the time to sort out what they were talking about. This was about the time when the Spring Framework was using some very similar ideas. As a result we came up with a new term: Dependency Injection. This essay describes my explanation of this idea as it was clarifying in 2004.
Many people are concerned about building a database in an evolutionary manner. How can you change a database schema when you have a production database full of valuable data? My colleague Pramod Sadalage has been at the forefront of solving this puzzle, ensuring that such database evolution is an unremarkable practice on ThoughtWorks projects. He collaborated with me in writing this article on his approach and later wrote a books on refactoring databases and recipes for continuous database integration.
During the mid 00’s I started mapping out some further enterprise application architecture patterns. This work stopped once I committed to my [DSL book] and at the moment I don’t know if I will restart it. There are, however, many interesting patterns here. In particular those on GUI architectures and MVC are widely referenced.
Remember these are work-in-progress drafts, really the equivalent to a author’s working papers, so the text isn’t very polished. I like having my working notes online, so other people can use them if they find them helpful. But that does mean you’ll need to be tolerant of particularly sloppy text.
A key part of the design and delivery approach I advocate is using automated regression tests as a bug-detection mechanism. This is vital both to reduce bugs and to enable refactoring. A common problem I’ve run into is when test suites decay due to tests failing unpredictably. Therefore it’s important to understand the common causes of this non-determinism: lack of isolation, asynchronous behavior, remote services, time, and resource leaks. Once you get the hang of why these are happening you are well on your way to fixing them and getting a regression suite you can rely on.
There’s a lot of talk these days about configuring web APIs as RESTful services. But as usual, a lot of talk doesn’t always mean a lot of understanding. Talking with my colleagues working on the Rest in Practice book, I found it very helpful to use this maturity model for REST developed by Leonard Richardson.
When testing many people use Test Doubles: alternative versions of collaborating objects specifically prepared for testing. Here I talk about the different kinds of Test Doubles that people use, and how they lead to a couple of distinct styles of unit testing.
It’s commonly thought that the provider of a service should design the interface based on its perception of how it may be used. Here Ian Robinson argues that service contracts should be driven by their consumers and the provider should aggregate their needs. This makes it easier to change an interface without messy versioning.
“Architecture” is often a dirty word in agile circles. During my tenure as editor of the design column for IEEE Software I wrote this column exploring the definition of architect and architecture in software. (Although the best quotes come from Ralph Johnson.)
- Enterprise Architects Join the Team by Rebecca Parsons
- Agilists and Architects: Allies not Adversaries a keynote I gave with Rebecca
- The Difference between Marketecture and Tarchitecture by Luke Hohmann
- Beyond Software Architecture where Luke explains all the bits architects usually neglect
During early object days in the 90’s many people discovered the key patterns that allowed us to make systems like this work in a layered architecture. Patterns of Enterprise Application Architecture captures this knowledge. Although tools and frameworks come and go, many of which implement these patterns, I think it’s still valuable to understand the patterns so you best know how to make good decisions in using them.
- Online catalog of patterns from the book
There used to be a notion that design was something you should finish before you start programming. When I was shown refactoring, I saw a disciplined technique to let a design evolve and improve during programming. So I wrote this book to pass on these techniques. Although the book is a decade old, the programming techniques inside have not aged.