Thursday, August 14, 2008

Organize Around the Architecture (#1)

Bookmark and Share

In a post titled “Contracts and Integration Tests for Component Interfaces” at Object Mentor, Dean Wampler discussed agile development and the communications between teams. As usual, Dean makes a number of good observations, and I’d like to pick up and expound on a couple of his thoughts.

For many years I led teams that had fully adopted agile practices. We had refined our development approach (and continually did so) to be extremely productive. Our responsibilities were almost exclusively for common services that were used at the enterprise level, which included everything from Credit Card Processing and Campaign Management to Subscriber Identity Verification. In those days, the overwhelming majority of the teams we worked with were still fully rooted in traditional/waterfall methods, and just like the teams Dean described, these teams were very reliant on BDUF.

Working with those teams, we were very quickly able to get ourselves into a position where we stayed barely ahead of them. We performed independent analysis in the business domain and consistently developed the services that would ultimately be needed. Of course, we always made sure not to get too far out in front where we might run too high a risk of disconnecting from or misunderstanding the true business objectives, needs, and priorities. Operating in this mode, there was at least a theoretical danger of building things we didn’t need, but in practice, over more than five years, that didn’t happen a single time. By maintaining close relationships with the “customers” (which included both the true business customer and the other development teams that would consume the services) and constantly communicating about their needs, we consistently blazed the trail just in front of where they wanted to go and made it possible for them to keep marching unencumbered towards their goals.

From a technology standpoint, we did something pretty similar to what Dean suggests. Though they’re absolutely a prerequisite, static definitions of contracts are not sufficient for reliable communications and assurance of unified expectations (see also Contracts are the Thing and Service Design Principles (The Contract Story Continues)). In our case, we delivered in four steps and provided the following in rapid succession to each team: 1) static definition of the contract, 2) client-side mock, 3) server-side mock, and 4) operational service. Sometimes this would all happen within just a sprint or two, and it always allowed the teams to actively participate in the evolving understanding of the dependency and how it could be incorporated into their design and delivery.

By the way, in those days (for calibrated reasons) we were exposing these capabilities as J2EE services, so part of our practice was to deliver a simple client library that encapsulated all the details about communicating with the service. This design was something we first delivered in 2001. It was in this thin library that the client-side mock was implemented. It allowed developers on those teams to start calling the service very early on, when they were ready, even if we were not. That mock remained available in the client library for future testing and development purposes and was typically activated by qualifying the service endpoint. With barely sufficient richness in the communication with the mock (e.g., the type of responses available), the dependent team was able to recognize potential integration pitfalls very early. This led to much greater accuracy, reliability, and validation of the interfaces.

You’ll notice that this approach heavily emphasizes the principle of “Organizing Around the Architecture,” which promotes segmenting a project or program into manageable sub-parts (and corresponding sub-teams) with clear and defined roles and responsibilities that in aggregate accomplish the goals of the overall initiative. Specifically, the dependency between each team should be in alignment with the architecture and in some fashion documented by the “contract” for the services being provided by those teams. For large-scale development programs, I consider this sort of organization to be essential. In fact, I think we all understand the importance of subdividing any large effort into manageable structures (and accountabilities).

Which brings me to my last point. Dean mentions the use of “virtual feature teams.” While that's a common approach and is often used successfully (especially for small to medium efforts where scope and scale are more easily managed), there’s an inherent risk in any approach that doesn’t respect the natural correlation between the structure of the organization (the people) and the structure of the architecture (the product). It’s been proven time and time again that the architecture of a product will tend to follow the organization of the people designing and delivering that product. I’ll talk more about this in a future post, but for now, as we think about the relationships between teams, how they’re structured, and how they communicate, let’s be sure to take the “Organize Around the Architecture” principle into account.