Wednesday, November 01, 2006

Software is like carpentry.
Given the user's requirements, programmers can probably build whatever is being asked for. It might look ugly, but if that's what the end user wants, and they're happy with the resulting product, then success, and profit! Sometimes you create a thing of beauty, and then success, and profit! In general, nobody wants to make something ugly, but circumstances might take that end result out of our control. (I refer you to the numerous articles at The Daily WTF for some examples)

One of the advantages of working with wood is that you can handle it pretty easily and fix constructions issues quickly. Things with steel are not the same. Steel isn't something you just casually pick up in your car or truck at a construction store, and it requires lots of other machinery (and people) to make things with. Now there's nothing wrong with steel as a raw material, but it means that you need to have anticipated a lot of things in advance and make some very great plans. Unfortunately, it also compromises your ability to adapt to changing requirements (and externally imposed limitations such as building codes), and it's entirely possible that if the design and plans are too inflexible, then you're going to be forced to generate a result that's not making everybody happy.

Building software is a little like that. Large projects need to be planned out well, the design needs to be in place and employees need to have some semblance of a strategy so that the business managers can figure out how everything gets paid for. However, one thing we have in software that they don't have in architecture is that we don't build our skyscrapers with steel.

The pliability of our raw material is great. It means we can still be responsive and address unforseen issues with less hassle than if we had built things out of steel. It doesn't mean that we can or should build our skyscrapers crooked on a whim, but it does mean that programmers have some room to make adjustments.

My big deal about this wood example is that your end result is what matters. Sure, it needs to be on schedule and budget, but it also needs to solve the problems that it was supposed to. And it should solve those problems well and your end users should be happy.

Instead of coming up with reasons to disprove why a new feature can't or shouldn't go in, just listen to your customer and take notes. You don't have to come up with the answer in that same instance, but just make sure you properly understand the problem being described. This is just as much about people skills as it is about technical prowess. Quite often, a non-technical user has a slightly different understanding of your system, and the solution might just be to move some UI elements around, or add new parameters.

One of the things that I do in my own coding is to account for future extensibility right there in my functions. For example, passing objects and data structures gives you a silent way to upgrade your system. A trivial example would be a function that calculates averages. An interface like:

float CalcAverage( float f1, float f2, float f3, float f4 );

is limited to only handling a fixed set of inputs. If your needs change, you'll have to track down all the places where this function was called and update them. If it's a large project, you might even miss some modules and be forced to revisit your updates later.

Worse yet, someone (hopefully not you) might cut-and-paste from this function to create variants for other uses. This means that certain kinds of bugs or other problems in the original can propagate to other functions, and the QA complexity has just increased.

Consider an interface like:

float CalcAverage( FloatArray f );

It's much more flexible. I'm not going to explain why because I didn't intend this to be that basic of a programming chat.

Build a reasonable amount of flexibility into your systems at design time. You'll greatly reduce the ramifications of changing requirements. It's much easier to maintain this kind of code, and you'll definitely get more work done.

Going back to the wood vs. steel analogy, software solutions have a lot of room for flexibility. Unlike the business of building skyscrapers, we have more freedom to change lots of things as we go along. It doesn't mean that we should (because that might throw the project way off schedule, or our product might lose its focus), but we should be responsive to the end user's needs and the project's goals. There's no point in releasing something useless, is there?

No comments: