The submission behind today's schedule article was withdrawn; instead, I'd like to take this opportunity to present the practice of Soft Coding.

Most programmers consider “Hard Coding” to be a Bad Thing: it’s hack-like, inelegant, and all-around lazy code. And as such, many programmers try their damnedest to avoid it. Unfortunately, this quest of avoidance often leads towards a much worse path: complication, convolution, and all-around unmaintainable code. It’s a path I like to call Soft Coding.

Before I discuss the finer details of Soft Coding, I’d like to briefly define Hard Coding. It’s the practice of embedding “things that shouldn’t be in source code” directly inside of source code. The definition is intentionally vague: while most would agree that database connection strings and logfile directories don’t belong in source code, there’s a lot of gray area. Take, for example, this following code:

private void attachSupplementalDocuments() { if (stateCode == "AZ" || stateCode == "TX") { //SR008-04X/I are always required in these states attachDocument("SR008-04X"); attachDocument("SR008-04XI"); } if (ledgerAmnt >= 500000) { //Ledger of 500K or more requires AUTHLDG-1A attachDocument("AUTHLDG-1A"); } if (coInsuredCount >= 5 && orgStatusCode != "CORP") { //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A attachDocument("AUTHCNS-1A"); } }

I can already feel some of you cringing: Magic Numbers; String Literals; eww, that’s a lot of Hard Coding! However, not a single character in that example is Hard Coded: there is nothing that “shouldn’t be in source code” in the above code. The function simply implements a very clear and very specific business requirement with very clear and very specific code. Anything less and it would be Soft Coded.

This brings us right into the definition of Soft Coding: the practice of removing “things that should be in source code” from source code and placing them in some external resource. It’s another intentionally vague definition with just as much gray area.

The Enterprise Rules Engine Revisited

Perhaps the most egregious example of Soft Coding I’ve ever seen was the Enterprise Rules Engine. The idea behind the ERE seemed innocent enough: business rules change often and the system should be able to handle these changes. The resulting conclusion and complexity that the ERE created was unfathomable.

In the year since I first discussed the Enterprise Rules Engine, the company behind it has actually managed to build a database schema to store their business rules. It looks something like this:

Fields (FieldId, DataTypeId, FieldName)

Atoms (AtomId, Field1Id, OperatorId, Field2Id)

AtomSets(AtomSetId, AtomId)

AtomGroups(AtomGroupId, AtomSetId, BooleanId)

AtomGroupSets(AtomGroupSetId, AtomGroupId)

… and so on

This improvement meant that, in order to implement a simple rule (say, “if (orderTotal > 50000 and ordersApproved < 3) then flagOrderForReview=true”), a developer must add or update anywhere between ten and thirty rows in the database. Although that may not sound so bad, imagine a floor full of developers concurrently working on this rules database. As difficult as it was to Soft Code the rules using C#, Soft Coding them in the database was monumentally more difficult and less productive.

In an effort to improve productivity, the Enterprise Rules Engine Team (yes, there is a full-time team dedicated to this monstrosity) is hard at work on a language syntax and parser that will allow developers to more easily maintain these database-stored rules. The idea is that it will be some sort of COmmon Business-Oriented Language that’s generic enough to code any rule and removes all of the “complexities” of “real” code like functions and that sort of thing. Imagine that.

Just Configure It!

{app.cfg} #used in docMgmt.java:attachSupplementalDocuments() LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000

Of course, I doubt any of us are deluded enough to create an Enterprise Rules Engine. But a lot of us – including this developer – occasionally find ourselves on the road of Soft Coding. It’s an easy path to stumble upon: at first you’re just trying to avoid Hard Coding, and next thing you know you’re drowning in a sea of Soft Coding. Looking back at the code example above (attachSupplementalDocuments), the most common “solution” to the “problem” of potentially changing business rules is a configuration file. I imagine some of you have already decided what you would make configurable above:

While this may seem innocent enough – and even “cleaner” to some – it’s the first very wrong step down Soft Code lane.

If every business rule constant was stored in some configuration file, life would be much difficult for everyone maintaining the software: there’d be a lot of code files that shared one, big file (or, the converse, a whole lot of tiny configuration files); deploying changes to the business rules require not new code, but manually changing the configuration files; and debugging is that much more difficult.

The one and only business rule change that this preceding Soft Coding could ever account for is a change in the ledger amount that required a form AUTHLDG-1A. Any other business rule change would require even more work – configuration, documentation, code, etc – to implement:

AUTHLDG-1A need not be attached if the client’s service level is at least three

CRTAUTH-CA1 should be attached in addition to AUTHLDG-1A

AUTHLDG-2A should be attached instead of AUTHLDG-1A if the ledger amount exceeds 1000000

Between Soft and Hard Code

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.

Those tools are designed to implement very specific business logic using very specific code. As the above code example demonstrates, there is no clearer way to represent the business logic for attaching supplemental documents. When the business logic changes, the code can change. It’s that simple.

The Dreaded Deployment

The primary fear behind the Fear of Code Change is The Dreaded Deployment. Soft coding doesn’t actually make deployments any easier; in fact, as the Enterprise Rules Engine shows us, it makes it even harder. And when you give end users the ability to change business rules, that’s a whole new nightmare.

But for some reason, many of us find comfort in deploying Soft-Coded changes. It just feels, pardon the pun, softer.

However, the solution to deployment issues is not to add another problem. It’s to address the actual issues. With the myriad of tools available today, there is no reason that your deployment process need be any more complicated than a simple, automated script that retrieves the code from source control, compiles it, copies/installs the executables, and then runs the relevant database scripts.

Well, that is, unless your program is laden with Soft-Coded business logic.