When developing software, there are three main options you have when it comes to coding a feature. They are: Hard-coded, Parametric, or Soft-coded (this term was invented by the guy who runs the site in the previous link). In order to discuss these three ways properly, we need an example feature to analyze – so let’s say that Requirement #118 of the application you are working on states that:
“There shall be a textbox called Name, followed by a button called Save. When Save is clicked, the value of Name will be saved.”
A Hard-coded feature is the old fashioned way of doing things – the boss tells you that #118 needs to be in the current release, so you fire up the trusty old compiler, punch in the code that places a textbox and button on the page, and then you code some sort of event handling code that saves the value of Name to the database. Sounds like this should be all there is to it, right?
But – let’s say that somewhere along the way, product management decides that in certain unknown cases, that the save button doesn’t actually need to save to the database, but instead needs to send an email to tech support. The clincher here is that the cases in which this has to happen are unknown – as in, unknown to the code. There is no way for the code to decide what to do at compile time.
So to handle this, you add a parameter or setting to a configuration file called “SaveToDBOrEmail”. When the value is “DB”, it will be saved to the database, and when its “Email”, it will be emailed (hopefully in the real world your parameter name and value choices would be a little smarter than this). This feature is now Parametric – its behavior is controlled by an outside parameter, and is not dependent solely on the lines of code that you have tucked away safely in your version control. So now, your installation team just has to install the software, ask the customer what they would like, and then set the value of that field, and things will behave as the customer wants them to.
In the third kind of feature coding, Soft-coding, things get slightly worse. Often what happens is product management can’t make a decision on what the product should look like, or your developers can’t think of an acceptable solution, so instead, they attempt to create a “framework” of a system that can then be given some configuration data and then do “anything”. This configuration might be stored in several forms – an XML document, a workflow diagram stored in a DLL or database, or any number of things.
In some cases, this approach can be OK. For instance, when providing for test manipulation in a reporting tool, I think its fine to allow the user to enter some VB script in a form that will do things like “Trim()” or “Uppercase()”. However, in most cases, a good majority of the functions in the system end up getting defined in the configuration. Not only does this tend to cause you to end up with a product wrapped around a custom solution, but it also means that the functionality of your system, instead of being coded in an efficient, easy to put-in-source-control language, ends up living in a configuration file! (See The Enterprise Rules Engine)
Perhaps the worst part of this is when you go to add a new customer, you may have to “code” all the configuration for the new customer from scratch in your configuration file. Additionally, updates to existing customers become next to impossible. (“Which part of this XML am I supposed to change to enable this field in version 1.8???”).
In almost all cases that I have run into, doing this sort of soft-coding is an Anti-Pattern. The only way to make a good product is to put some real thought into product design, determine the root functionality that your customers really need, and code to that goal. Trying to supplant good product design with endlessly extensible systems is a recipe for disaster.