The reason we find ourselves Soft Coding is because we fear change. Not the normal Fear of Change, but the fear that the code we write will have to be changed as a result of a business rule change.It’s a pretty silly fear to have. The whole point of software (hence, the “soft”) is that it can change that it will change. The only way to insulate your software from business rule changes is to build a completely generic program that’s devoid of all business rules yet can implement any rule. Oh, and they’ve already built that tool. It’s called C++. And Java. And C#. And Basic. And, dare I say, COBOL.
From time to time I fight this battle at work. For example, at one point we needed to restart the radio daemon when installing a simulation model that contained a radio component.
Another developer argued that we should:
- Modify our component code generator so that you could specify a restart-radio flag in a component definition.
- Modify our radio components to set this flag.
- Add this flag to the XML generated for a component.
- Make the model installer notice this flag, and restart the daemon.
All this work, scattered across three sets of code, to avoid the stomach-churning terror of having to write:
has_radio = False
for obj in model:
if obj.group == 'Radio':
has_radio = True
if has_radio:
restart_daemon()
So, instead of writing 6 lines of straightforward Python code,
(In fact, there's already a model.has_radio() method that contains the loop above, but I thought using it in the above example would make it too trivial-looking: only 2 lines.)
Imagine that, one bright and shining day, the installer mysteriously stops restarting the daemon. In my version, the code to debug is mostly right there: is the value of has_radio determined correctly? Is the model the one we expect? Are the components all being looped over? In the indirect version, you have to trace bugs back through the components: is the installer parsing the XML properly? Is the flag in the XML as expected? Is the code generator noticing the field in the definition?
I fight this battle a lot at work, and usually lose. (We do love having a lot of daemons and interfaces...) In this case, things ended happily with a rewrite so that the daemon restart is no longer needed at all.