Wednesday, September 8, 2010

Selling Software Design

There's a new software project starting up and you are assigned as the architect or technical lead on the team. Your first task is to plan and design the overall architecture to best address the requirements and the risks. To do this you rely on best practices, design patterns and past experience. After bouncing a few ideas off of some peers, you come out with an architecture that you are proud of.

Your second task is to present it to the rest of the team.

Depending on how your office operates, this part can sometimes be harder than the first especially if you have team members that you haven't worked with before. The success of any up front design depends largely on team buy-in. If they don't believe in the design, then it will come out half baked and fall apart in no time.

Ideally, you would engage your teammates early on in the design process. You obviously shouldn't go design in a dark corner and come out swinging diagrams and specifications at everyone in a command and conquer fashion. You are part of a team after all. But, on the flip side, you don't want to have ten people arguing about minor details endlessly. In software, very few things are black and white and in the end you still need someone to stop and make a decision.

At first, when someone shows some resistance to your design, they might come off as being lazy or cowboy coders. This is not necessarily true. You spent hours thinking of different ways to bring all the pieces together and formed an extremely detailed picture in your head. It's often difficult to step back and remember that others do not automatically get that big picture handed over verbatim. I bet most of the time the resistance comes from failing to properly communicate that big picture. In those cases, resistance is your friend. Encourage it. Get your team talking and challenging your design. Their questions and criticism will result in one of two things:
  1. they found a flaw in your design and it can now be addressed before a single line of code is written
  2. they misunderstood or missed something and you have the opportunity to clarify
Expect these conversations from the start and come prepared. Some of the design decisions that you'll make will appear to mean "more work". Whether it's more boilerplate code, or figuring out how to preserve context across decoupled layers, or just doing things in a way that is not obvious; implementing these decisions takes time and diligence. If it came for free, it wouldn't be a design decision, it would just be how you do things. So, if you are going to ask that of your teammates, you need to make it clear how these short-term pains will pay them back in the long run. After all, that is why those decisions were made, right? If you can't come up with a better reason than "The GoF said so", then you are over engineering.

Be prepared, but be flexible. You are not perfect. You work with smart people who have their own experience and creativity to contribute. Use it. Mix it in with yours and everyone else's and see what kind of soup you end up with. Not only will you improve the design but you'll make it a product of the entire team. Your teammates will be more likely to appreciate and respect the design if its their baby too.

Test drive your design. This is especially important if you're the only one on the team during the initial design phase. Boot strap the project and write some code. Pick a depth-first feature as opposed to breadth-first. What I mean is write a component that will drill deep into the layers of the architecture. A good candidate for this is usually something like the login/authentication component since it requires code to that goes from the GUI to the backend effectively traversing a good chunk of your design. Try implementing this in a TDD fashion using unit tests with stubs and mock data. Not only will you be validating your design, but you'll be setting a pattern. When the rest of the team jumps in, they'll have something to work from. They'll have working examples of how to create their model classes, make services calls and even how to capitalize their variable names.

Getting those doubts and concerns articulated right from the start will help get the project started on the right foot. It will set the mood for the remainder of the project and help implement the design so that it can be maintained in the long run. Of course it doesn't mean that it will maintain itself, but I'll leave that topic for another blog post.