JFHCIThe evil that is configuration

time to read 3 min | 599 words

 

 Chris Ortman asks a very good question about my just hard code it post:

image

I really like the simplicity of the approach, but does this impose a requirement that in order to change the discount percentage of the system I must be able to write c# code? I think it would not take very long for someone to ask me for and 'admin' screen to do that.

I run into this all the time with new features that would be trivial to implement if not for the database table to hold the settings, the model to work with the table, and the admin screen to edit it. How do we get from 'enter 5 into this box in the admin screen' to write class that applies the discount percentage you want .

I have a very simple answer for that. You don't provide any sort of admin screen, and you don't provide any way for a business user to go into the system and make a change. To start with, the system administrator has no idea what are the implications of changing such a configuration. Next, we have the standard issues of when we reload the value, validation, etc. All sorts of things that we really don't want to deal with unless we have to. Not to mentions that the idea of letting anyone the option to modify operational parameters without regard to testing and QA makes me very unhappy.

All of those are workable with enough effort, however. What is not workable is the end result of such a system. Here is what you'll end up with:

image

Remember, we expect to have a lot of such rules. So we expect to have a lot of configuration values. And don't get me started on reusing configuration values for different purposes, just because a dev saw something that looked even somewhat similar to what they were doing now.

Given this piece of code, then, how are we going to handle a changing business condition? Let us say that we want to offer this only to preferred members after the first 6 months:

public class DiscountPreferredMembers : OnOrderSubmittal
{
	public override void Execute()
	{
		if ( User.IsPreferred )	
			Order.AddDiscountPrecentage(5);
	}
}

This is trivially simple:

public class DiscountPreferredMembers : OnOrderSubmittal
{
	public override void Execute()
	{
		if ( User.IsPreferred && DateTime.Now > User.PreferredMemberSince.AddMonths(6) )	
			Order.AddDiscountPrecentage(5);
	}
}

Compile this rule (which will usually be in a separate project, along with a bunch of other tightly related rules) and push it to production. If you are doing an out of band release, you might want to do it in a completely separate DLL.

And yes, we are still talking about using the lowest common denominator, without introducing any concept more complex than a class and the if statement. More advance solution would be a DSL, in which the deployment unit would be the individual script, instead of a full DLL.

But even so, I hope that I am demonstrating the concept.

All we have to do is to stop thinking about the code as set in stone and accept that this is one of the richer way we have to express semantics.

More posts in "JFHCI" series:

  1. (27 Aug 2008) Quote of the Day
  2. (22 Aug 2008) Considering Scale
  3. (22 Aug 2008) The evil that is configuration