How I learned Conway's law the hard way
I dislike it when people at work quote "laws", "rules" and other platitudes like: "Adding people to a late project only makes it later", "You can't produce a baby in one month by getting nine women pregnant", "the Pareto principle". Often they are a way to kill discussions and give up critical thinking, or just hide the fact that you don't know what you are talking about. And in the worst case, the discussion turns into a contest about who knows more of these rules.
One of the quotes that triggers me is Conway's law: "Organizations design systems that mirror their own communication structure". It's not wrong, but I came to dislike it because I have seen it used as an argument for separating people in "component teams" that mirror some kind of arbitrary, up-front software architecture. I'm a fan of "feature teams" or "vertical teams" and "emerging architectures" and I believe that throwing a (good) bunch of people together to implement a, possibly bare-bones, system end-to-end will yield better results. Another technique I like is the "tracer bullet" and I don't think you can really do it unless the people implementing the tracer bullet are sticking close together, which is easier to do if they are a single team. Separating people in teams usually means creating conflicting goals, implicit distrust, us vs them attitude, developing things in isolation, lack of shared customer understanding etc. It also means spending a lot of time debating about priorities of one customer team vs another.
For example in Meego, many of the early problems we had were because we separated applications and framework teams too early, whereas it would have been much better to start with one team developing both (a framework and a few "hero" applications) and then separating them later. We ended up doing some of that later down the line and things got much better.
However a recent experience changed my mind. In this case the products were the applications, but also the framework used to build them, which was productized as a separate SDK. For historical reasons, the team building the framework was also the team building one of the applications, and other teams were building other applications and the tooling around the framework. When I started, I was advised to follow Conway's law and split the teams so that the framework would be an independent team, and all the applications its customers. My first instinct was to reject it and instead consider the framework a shared code that all teams would contribute to to support their end customers' goals. From my past experience, I was afraid that if I split the team, in the framework team we would just debate about priorities of different customers, while the applications teams would be stuck complaining that the framework team wasn't supporting them to meet their goals (I have seen this happen). The end result however was that:
- the people with most knowledge of the framework where stuck also developing an application and had to spend time on non-framework related work
- the framework and application developed with it were a "monolith", and the application violated the layers of the architecture
- application teams contributing to the framework were constantly breaking each other's functionality
To be fair all these issues could have been at least partially solved by requiring that the framework was used only in binary form, and having better CI. But it was very hard to put these constraints on each team, and would have been much easier to just separate the teams according to the intended architecture.
So I came to the conclusion that yes, Conway's law is a thing and if you want to enforce a certain architecture, the best way to do it is to organize the teams accordingly. The corollary is that a software architect needs to be an "organization architect" as well.