Any significant design decisions should be discussed and approved by the team. There is a fine line to be walked here between getting people’s buy-in and the dreaded ‘‘design by consensus’’ syndrome, but I think it is an important rule to establish. Design by consensus cannot work and is never what you want your team to spend their time on. Everyone has opinions about how every piece of code should be designed, but at some point, there needs to be one hand on the tiller. The role of designer/architect is an important one, but ‘‘architect’’ doesn’t need to be synonymous with ‘‘autocrat.’’
Personally, I favor an approach in which one or a small team of architects sketch out an initial design, preferably as part of a baseline architecture. That means building out as wide a solution as possible that touches all the riskiest parts of the design without going too deep. You want to prove that the solution is viable without spending much time building features. Once that initial work has been done, additional design work falls to the rest of the team. The architect should be responsible for the top-level design, but asking the architect to be responsible for designing every corner of the system is neither practical nor beneficial. That means that there will be some design work assigned to each member of the team as they build ‘‘down’’ or add features to the skeleton established by the baseline architecture.
That said, it is still the responsibility of the architect to make sure that the overall design expresses a consistent vision of how the system should work and how the code should be laid out. To that end, any significant design decision that is made during the course of building out the system should be raised with the group and discussed so that the architect can approve it. That doesn’t mean that everyone on the team gets a vote. Nothing paralyzes a team faster than trying to reach consensus on every design point. No group of developers larger than one will ever agree on everything, and trying to get a team of 10–12 developers to reach consensus on design decisions will cause your project to bog down in short order.
However, if significant decisions get raised with the team and discussed, everyone benefits. The architect may be exposed to new ideas that he or she hadn’t considered before, or specific aspects of the system’s domain may come to light that make design changes necessary. If those decisions are raised in the context of the group, everyone learns from them, and you will have a better chance of staying consistent throughout the project and as a team. What you really want to avoid is any surprises that the architect might stumble across later during development. If parts of the system are inconsistent with the rest of the code or with the goals of the architect, then everyone’s job becomes more difficult. You end up either just living with the inconsistencies or ripping out and redoing work that has already been done, which doesn’t make anyone happy.
This is one of the harder rules to uphold, unfortunately. It really requires the architect to be involved at code level across large swaths of the software. Spot checking may be enough, although there are tools that will give hints as to where there might be issues. Using the source control system to track where changes are being made helps to identify ‘‘hot spots’’ where lots of changes are happening at once. Looking for new files being checked in can help find new areas of functionality being added. And occasionally generating artifacts like class diagrams may help highlight areas of interest.
The most important tool that the architect can employ is communication. Talk to your team and ask them what they are working on. Do they have questions? Do they need help? Are they unsure about anything? Do they understand how their work fits in to the system as a whole? Watercooler chat is a great way to identify which parts of the code may need extra scrutiny.
So how do you identify a ‘‘significant’’ design decision? Adding a new class isn’t significant. Adding a new interface might need to be double-checked, but maybe not. Adding a new abstract base class probably bears looking at. Introducing a new third-party component or tool definitely is significant. As an architect, you really don’t want to find out a month into development that one developer has introduced an inversion of control container into their code independently of the rest of the team. Ultimately it is up to the team to decide what will constitute a significant change. Just make sure that everyone understands it in the same way, so no one is surprised.
Before any task can be done, any design issues that are included in that task need to be brought to the attention of the team and the architect and signed off on before the task can be considered completed. If such issues are brought up on a task-by-task basis, there is less chance of things slipping in and persisting in the code for a long time before being noticed.