In the early days of software development (1967), Melvin Conway observed that “organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.” In other words, the structure of the software followed the structure of the organization. I’m here to tell you that – for fully capable development organizations – this is “the tail wagging the dog.”
Let’s step back a bit in order to get on the same page about what’s going on here. When rolling out an application, there is rarely just on piece of software. There was a time when one application was written on top of an operating system, and it interacted with a single user sitting at the keyboard. This was called a monolithic application because it was all “one thing”. It was one piece of code (possibly compiled from multiple source files) deployed in one process, run by one user.
Often, architecting within these middleware products involves writing small pieces of code that fit precisely into a specific framework. The modern unit of software development is a “module”, with a well-defined interface. A good distribution of features across modules exhibits:
- Cohesion – Features within a module “make sense” together.
- Loose coupling – Changes in one module (generally) don’t cause changes in another (or other) modules.
Cohesion often means that things change at about the same rate, and due to similar forces, for example, business model, additional market segments, etc. These terms have widely accepted definitions, but in practice they are applied with a high level of subjectivity. Usually, an experienced architect will move features around in modules until “it just feels right.”
The structure of the software should drive the structure of the development organization
The purpose of this blog entry is not to help you get better at identifying modules, but instead is to show that the structure of your software should drive the structure of your development organization. During development, the people working on the same module will have informal, high-bandwidth communication. If they aren’t co-located, there should be tools in place that support high communication among geographically dispersed teams (e.g., Slack, Skype, screen sharing, etc.).
People working on different modules will have formal, low-bandwidth communication. This will probably take place between team leads (if each module has a team and team lead), or between the architect and each team. It is formal because the interface that each module implements is well-defined, and (hopefully) relatively consistent over time. It should be low-bandwidth because each participant should be only interested in the meaning of the interface, not in how it is implemented. There might be “hints” passed around like, “If you make this API call, and then that one, you’ll get better performance than the reverse.”
All of this is true whether the modules are being developed all by the same company, or if you are integrating with a 3rd-party module (e.g., Salesforce, Workday, Oracle Cloud Suite, etc.). The over-riding objective is to reduce the communication overhead required to deliver the software.
If you can structure your development organization around your architecture, you will avoid putting the cart before the horse, and reducing the communication overhead. People will feel like there communication patterns are in alignment with direction of the software, and everyone will be more efficient.