I’m a sports junkie and one of my favorite times of the year is the weeks leading up to the NFL draft. When discussing draft candidates at offensive line you’ll often read a scout using the phrase “strong at the point of attack.” The player isn’t just a workout warrior in the weightroom. He’s able to bring that ability to bear in game situations where it matters most. In the same sense I’d like to see this applied to software development.
I think the general model of one or few architects or technical leads designing to many developers just coding is a flawed model. There’s a tenuous boundary between coding, design, and architecture. I think it’s a mistake to overlook the impact of one upon the other. The quality of a system’s code is largely the sum of a lot of small decisions more than the first couple big architectural decisions. In order to get these small decisions (where should this code go?) right we need to put skill at designing software right at the point of attack — the developer’s keyboard. Having all of the design knowledge embodied in a handful of architects is like putting hundred pound weaklings on your offensive line while the three hundred-pounders coach from the sideline.
A software design generally doesn’t spring forth like Athena jumping out fully formed from Zeus’s forehead. I’m a devotee of the Extreme Programming creed. We don’t build architectures and designs, we grow them over time. Successful continuous designs aren’t willy nilly code n’fix either. Continuous design efforts require constant attention to weed out bad code, remove the rough edges around designs, eliminate duplication wherever it’s found, and always look for better abstractions. This organic approach to design can only work if the people doing the coding are skilled in software design enough to recognize problems and opportunities for improvement in the design.
There’s a saying attributed to open source software that goes “with enough eyeballs all bugs are shallow.” One of the reasons that I don’t believe in the “one architect, many coders” model is the dampening of the feedback loop. If I’m doing all or most of the design and little of the actual coding I’m not getting much direct feedback about my design. I’m effectively flying by instruments and intuition alone. It’s better for me as a designer of software if I have to feel the “pain” from the design decisions I make. The final arbiter of design quality is often coding that design. Many things that seem perfectly valid on a whiteboard or in UML diagrams break down when you hit the actual code because of something you didn’t consider, or a better idea rears its head. You need to be able to get that feedback and adjust to arrive at a better design. Since no one person can code all of a big system by himself, every other developer needs to be a pair of eyes and ears into the design to gather more feedback. Every developer might not be able to contribute to the formulation of the design, but they should at least be able to spot things like duplication, violations of encapsulation, and unnecessary complexity. Give every developer some modicum of design knowledge, put their eyeballs onto the code, and make many of your design problems shallow problems.
I’ve said several times on this blog that the hardest and most critical part of creating a software design and architecture isn’t the actual creation, but rather the socialization of that design throughout the team. The perfect design isn’t helpful if the team doesn’t understand it enough to implement it (which pretty well eliminates the “perfect” from that sentence). On the other hand, if the team as a whole understands the “why” behind the design choices, they’re much more likely to carry out that design well. My experience says that this socialization happens more effectively when there’s a lot of discussion within the team both early in the project and throughout the project. Some leadership is still required to start the conversations and keep the conversations from stilting as the team can go head’s down under pressure schedule. Having a design determined by one or a few persons then dictated to the team never seems to work as well for socialization. Obviously, the flatter, collaborative model of growing a design is only going to be as good as the design skills of the team as a whole — yet one more reason to spread design skills downward.
Socializing the design and spreading design skill into the team at large should give the team a much better chance of knowing when to opt out of the general architecture when exception cases arise. Some of the worst designs I’ve seen have been caused by an unbending devotion to a design that didn’t make sense in its current context. For example, one of the two systems I’m working on uses a Supervising Controller architecture for most of the main screens, but we’ve found it useful to ditch that pattern for some one off screens. I want the developers on my team (all two of us, but you get the point) to know when it’s better to deviate from our standard screen structure.
What about the Architect?
I wanted to leave the neverending debate over the duties or even existence of an architect role out of this post, but it’s basically impossible. I’ve been mostly hostile to the idea of a dedicated architect in the past because of several bad experiences (and close to disdainful of most of the people calling themselves an “architect” in the .Net world), but I have the utmost respect for architecture and design skill. I’ve been on projects where I thought it was highly advantageous to have a dedicated architect, but those projects involved integration across multiple systems and teams. In the end, I think my viewpoint is that “strength at the point of attack” is more important than the architect role. If the architect role actually detracts from this, then you simply can’t afford to make someone an architect.
Removing your most talented developers and most skilled software designers from the day to day coding work and low level design usually isn’t the right way to go. I think sometimes the architect role effectively pulls your strongest people off into a role where they have less impact on the quality of the design. My experience is that I’ve had much more positive impact on projects when I’m completely inside the development team than the projects where I was strictly an architect. If you have somebody with great design skills and a team that’s otherwise without design skill, I’d much rather that the person with the skills be put into a role where they can coach the other developers to spread out that knowledge. I don’t like divorcing the design skill, knowledge, and experience from the team building the software. I’d rather have those qualities applied at the point of attack.
I know where the pushback to the previous paragraph is going to come from. The average bigger shop doesn’t have enough architect caliber guys to go around, so they try to keep the architects out of the muck and strictly focused on design and architecture. Even worse is when a shop try’s to share architects over multiple projects at any one time, watering down the potential contributions of their architect folks. I think these shops need to be cognizant of the compromise that they’re making. They simply don’t have enough talent to go around for the project work on their plate. Since I don’t think the end results can be anything but mediocre without strength at the point of attack, I’d much rather cut down on the number of projects, and put the detached architects in a position to do as much coaching as possible to grow the people you already have. In formulating the tradeoffs of having a dedicated architect, I think we need to factor in the potential for making every other developer better. In the short term it might be more efficient to have the architect making all of the decisions, but in the long run it’s better to teach the other developers how to make decisions themselves.
What I’m aiming for here is no less than the full democratization of design skill. Design skill shouldn’t be the strict purview of any kind of elite that remains aloof from the rest of the project teams. Chip Lemmon expressed some concern that the ALT.NET event this weekend could lead to some runaway elitism that wouldn’t do a thing for the average developer. Possibly, but one of the topics I want to discuss is what, if anything, can we do to start raising the general level of design knowledge throughout the larger developer population. What’s the best way to coach other developers? How do we make the skills and tools we’re de facto espousing under the ALT.NET banner common enough to make them viable in the community at large? All these questions are going to come up. I’ll blog the proceedings…