(For those who don’t code, don’t be intimidated by the code snippets in this question, they question is about approach to changing a design rather than the code design itself).
Recently I put forward a technical design that looks like this
public class MyDatabaseLayer
{
public ResponseCode runQuery(Query q)
{
try
{
//do database stuff
}
catch
{
//catch database exceptions (like bad username/password) and put them into a user friendly ResponseCode
}
return r;
}
}
However according to the ‘throw early, catch late’ principle, my design should look more like this:
public class MyDatabaseLayer
{
public ResponseCode runQuery(Query q) throws SomeDatabaseExceptions
{
//do database stuff without handling exceptions
return r;
}
}
The question is, it’s already late in the design phase, and I’ve already thought about how the original solution would work.
The project is quite simple, and so I’m sure that there will be no problems in either coding the solution, nor modifying it in the future.
I think that changing the design at this stage is just going to delay it and have me going around in circles without actually delivering a working product.
The question is, what techniques are there for dealing with this kind of issue, of whether I refactor the code to make it ‘perfect’ vs getting on and delivering it as ‘good enough’?
0
Ask yourself three questions:
- Do we have the resource to change the design now? If not, leave it alone.
- Is a design change now likely to add more value to the product over its lifetime? If not, leave it alone.
- Is there something better that I could be doing with my resources? If so, do it instead.
The point of doing anything, be it building software, designing a product, doing chores etc. is to replace a low value alternative for a higher one. for example, I clean my kitchen floor because I value its cleanliness over the effort it takes to clean it.
So, if “improvements” to a design are intended to make it confirm to a certain design principle, but don’t add any real value, then there is no point in making them.
The problem with all this is that nobody can be cerain what will happen in the future. This means that any effort I put in to improving things today might well be wasted effort. For example, I get the oil in my car changed regularly because doing so will, hopefully, help to extend its life. However, if my car gets written off just after an oil change then I’ve wasted my money.
The solution to this dilemma is to make a best guess based on the information that I have available. As an aid to doing so, people have come up with rules or principles that guide them in ways to add most value at least cost. This is where things like software design principles come in, but similar heuristics can be applied to many other areas of life.
The challange is picking the right principle at the right time. Of coruse, there are no hard-and-fast rules for doing so, but fortunately, there are (not surprisingly) principles that you can apply.
Here are some:
- Understand why something is considered best practice.
- Understand the the types of situations to which the principle pertains
- … and to which it doesn’t.
- Compare these to your current situation.
- Unsterstand the cost of imlementing the principle.
- …and the benefits that are likely to result from applying it.
- Determine whether you have the resource to apply the principle now.
- Learn from experience, both yours and that of others who have done similar work.
- Consider whether you could make incremental improvements, rather than trying to change everything all at once.
One final thing to remember is that costs and benefits are complex and often slippery things. Going back to my example of cleaning my kitchen floor, the time I spend cleaning it has both immediate benefits (it looks nicer), mid-term benefits (my wife is happy, and our relationship improves as a result) and long-term benefits (it lasts longer, we’re not likely to pick up nasty diseases from the mouldy stuff that festers in the corners). The immediate benefits may not seem so important… but some of the others are critical. Many of the benefits of good design in software are similar. In particular, good design frees up “headspace” that can be used to solve other – often deeper – problems.
I think that changing the design at this stage is just going to delay
it and have me going around in circles without actually delivering a
working product.
I think this is the money quote. You are not there to write good or beautiful code. You are there to create software that creates value for someone and that is sold. Good design is not a goal in itself. It is desirable only insofar as it allows you to create better software, e.g., by making it easier to maintain or to extend.
Agile software development addresses exactly this issue. The agile way of looking at you issue would be to deliver the suboptimal agreed-upon design now to have a working piece of software as soon as possible… but be very open to refactoring later.
There of course is a lot of leeway involved here. Nobody advocates just sitting down to code “to get something working fast” without planning what you are doing and doing actual design work beforehand. But if you feel the impulse of deviating from a planned course of action before having a working product, to improve design, then agile software development would tell you to step on that impulse and not act on it. Get something out the door, collect feedback, and then think about refactoring.
1