- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Business rule values are always inevitably bound to their behavior. Configuration options don't do here. Best thing maintainability-wise is probably to separate the entire set of business rules into it's own set of files, values and code included. Maybe one can call it some sort of layer... A tier, even. I'm a genius.
Admin
This is the best article yet. Seriously. A set of resources that define the runtime behavior of the program is basically another set of code, only one that is written in a weird application-specific language. Deploying an EXE is exactly the same amount of work as deploying a new set of data files. Generally you're going to distribute them together because otherwise the number of combinations will explode (imagine v1.0 exe with v1.2 data). Testing the application is the same amount of work whether or not the code exists in the EXE or in data files. Debugging is harder because there is code that comes from configuration files and chances are you didn't build a debugger for your homegrown data language. As others have said, using a dynamic language like Perl, Ruby, Tcl, Lisp, Scheme, can allow you to easily have runtime loadable code if you think you might want it. But implementing functions that execute data based on rules is a huge waste of time.
Admin
A set of "config files" can also be used to generate code. The code then doesn't interpret the config files at runtime, rather source files are generated from the "config files", compiled, and deployed. I like that idea. Works for lots of things, but obviously not everything! Makes repetitive tasks easy, makes for standardised source code adhering to a predicatable style and pattern, can make debugging of the generated source simpler, can make for highly-performing code, or rather code that doesn't run like a dog, and often makes for simpler deployment processes. An obvious shortcoming of generated code is the maintenance of:
Admin
Funny you bring this one up. I had this exact example on a project (COBOL based) about 20 years ago where the requirement was to process payruns on Tuesdays until the end of time.
The developers refused to do this even though it was a legal requirement because they'd have to "hard code" all future dates which were Tuesdays into their module (there was only one affected), and the Team Lead came over to gently put me right about modern development techniques.
After I pointed out the mod-7 trick above, he went off perfectly happy - "chuffed" actually, because it was a neat trick he hadn't seen before.
They still hard-coded the '7' and the '2' (the week begins on Sunday) though.
Admin
Very, very good article indeed. I used to be responsible for maintaining and debugging a platform that could have been simply implemented with Java, but no, of course it also included all kinds of differently formatted config files, XML files and also some configs in database. It really made me think about the correct level of abstraction. And yes, it is not an easy puzzle to solve!
Admin
That's neatly rephrased in Greenspun's Tenth Rule: Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
And of course, due to Zawinski's Law, it will also read your mail.
I think I might like to try a different approach for my next application. Start with an MUA written in Common Lisp and hack it until it also does whatever else I need.
-L
Admin
This has nothing to do with the value changing, but about readability.
Agreed, silly.
This has nothing to do with the value changing, but about readability.
Admin
I think it's safe to say that the lesson is to know why you are coding what you are coding the way you are coding it and have captured all of the necessary information to make an itelligent decision on how to do so.
Admin
I had an intro programming professor who preached what he called "the rule of three":
If you use a value more than three times across your module(s), it should become a named constant; if you use a section of code three or more times, it should become a function. That seemed to strike a balance against overly generalizing into "soft coding" while realizing some of the performance benefits of "hard coding".
Admin
If I remember there were some Christian fuckwits in Kansas (it's always Kansas) that wanted pi to be 3 because of something in the bible, so no you couldn't hardcode this, in fact you couldn't use the constant PI in your calculation.
Admin
Most readers seem to be missing the point: this is not about defined or inline constants, it is about configuration/overly data driven apps.
Admin
I just can't get myself to agree with this article.
Admin
A beautifully written article.
Admin
Admin
I wish you were the one I inherited code from instead of the person I really did. :-)
The (Delphi) code is full of things like:
const bUsePrinter = True; bUseScreen = False;
procedure DoReport(Data: Whatever; Destination: boolean);
And in the calling code:
Res := MessageBox('Click OK to print, or Cancel to preview', mtConfirmation, [mbYes, mbNo], 0); if Res = mbYes then DoReport(intData, bUsePrinter) else DoReport(intData, bNoPrinter);
I really, really hate it! :-)
(And yes, the other WTF-worthy stuff is really there too.)
Admin
This whole conversation deserves to be a WTF of it's own.
Admin
Hmm.
This looks like a job for an IDocumentAttachmentStrategy.
Or has GOF stuff become WTF now?
--GF
Admin
Actually, it was Indiana, and it had to do with bad and lazy mathematicians, not Christians, no matter what your opinion of them.
See http://www.straightdope.com/classics/a3_341.html
Admin
which is a shame, because what do you think you are doing when you do any (non-trivial) programming? People have mentioned Greenspun's Tenth Rule, which I actually have never heard of. What I have heard of is the saying 'Ask a computer scientist to solve a problem, and he will come back with a language perfectly designed for solving your problem in'. Ok its probably an old maxim, which probably felt more true back when you had to have a high level degree to even look at a computer. However both sayings are really trying to say the same thing. This is not meant as a bad thing either.
However, I can't really back the main article. Many people have allready pointed out the problems in coding. Really there is never an excuse to not put that hardcoded value into a constant defined at the top of your file. However, the article does seem to imply that it has more to do with configuration files. Yes, there is such a thing as having to many config files spread over to many places. In fact, you're config file will probably be defined in a config file if you're not carefull. This tells you that you probably have a bad design. probably.
However, there is almost never an excuse for hardcoding. Certainly not 'my app won't be used more than once' (or any small number). How many legacy apps/scripts exist that were only meant to be used once?
What it all comes down to is good design. Seperate your business logic from your presentation, etc., etc.. Avoid use of modern design and patterns simply to be using modern designs and patterns. Not everything needs to be in a config file, but unless its 0, put constants where they belong. It improves readability and maintainability. Yes, even if you use them only once, because maybe you only thought that when you started. No to mention that if you have to change the value of Pi, it's easier to do it in a defined consant the searching your file for it. Maybe not much easier, but still.
Oh, and all rules have exceptions. except this one ;}
Just one more thing. If your system, designed to make life easier, requires an expert to use it, maybe it's because the subject matter is difficult enough to warrant an expert. Otherwise you did something wrong.
Admin
I remember a class with Marshall Kline (of the C++ FAQ) who recommended a serious soft-coding approach for certain types of problems. But, he also offered this line of wisdom: Look at how the Good Lord designed your arm. It only has three well-engineered joints, which still offer an almost complete range of flexibility and movement. If you were missing an elbow, say, then your arm would be almost useless. But, if you added a couple more joints, then you wouldn' have an arm -- you would have a noodle.
Only add flexibility exactly where you need it.
Admin
Some QA departments actually take their task seriously and try to Assure the Quality of the product. That includes doing both black- and white-box testing and their own code reviews. Not very damn common, but it does happen.
Admin
What these people fail to realize is that they just moved the code into the database, so they were writing a compiler to execute the code in this database. I've seen this before and it failed miserably (except for my company which was billing by the hour to create this monstrosity). What a mess!
Admin
Holy moly, let the worms proceed forth from the can. My code base used to have the exact same lines (obj.stateCode == "TX"). I centralized all the instances of states into one unit and added a function so that the calls changed to stateOf(TEXAS).
I suppose that's too soft...
Admin
Count me in the group that favors constants.
The ONE_MILLION one is garbage--no constant should be named like that, one million isn't meaningful. Rather, it should be named what it's for.
Yes, you can do the same thing with comments. Think the comments will be up to date, though? My philosophy is that in almost all cases the only thing to comment should be algorithms or externals. If you need any other sort of comment the code isn't clear enough. Note that this occasionally means moving code into a procedure just to put a name on it but so what?
Admin
That's an unsupported assertion, one that I think is provably false. If you follow your logic to it's "logical conclusion", there is no point to any language other than machine language. After all, they're all just languages sitting on top of that. Clearly, though, higher levels of abstraction do have value and even you likely don't code machine code by hand. The point to any language that sits on top of a lower level of abstraction should be to provide useful abstractions that make doing common tasks easier. That's the fundamental reason why programming languages exist. It is definitely not the case that every problem requires a full-fledged programming language to solve. My example of computing an IRS 1040 is a perfect case in point. Externalizing the logic of the 1040 to a document that is read by a processor in no way requires a full programming language. The set of operations required is much more limited and specialized. So making an assertion that externaling logic leads inevitably to full-fledged-language-horror is just wrongheaded.
Which entirely misses the point I made -- just because something can or has been done badly doesn't mean it shouldn't be done. You or someone you know might not be the best person to solve a particular problem, but that doesn't mean no one is qualified and should attempt the task. Most coders I've met are terrible system architects, but that doesn't mean there aren't good architects that you should have designing your system. Likewise, externalizing logic requires a certain skill and has an art to it--if you lack that art, don't assume everyone else does and that the approach is therefore flawed.
Admin
You're thinking inside the box. There is a middle ground between a general purpose language (i.e. hard-coding) and throwing stuff in config files (i.e. soft-coding). That middle ground is a domain-specific language (DSL) which is used to generate code. You make it easy to write the business rules in a reasonably straightforward and natural way and make generating the code (and compiling it) part of the build system. As long as you don't try to make your DSL too big or your generator too smart, you're in good shape. It's still code, but it's code in a higher level language.
Admin
http://en.wikipedia.org/wiki/French_Republican_Calendar#Ten_days_of_the_week http://en.wikipedia.org/wiki/Discordian_calendar
Perhaps you should rephrase that:
"There are always seven days a week when I choose which calendar to use"
Admin
I use "soft coding" to create a framework for simple web forms. Let's say you are writing survey software and you have three clients. Each client will want different questions. So you have to create "components" for them to administer. You give them the textbox, radio, checkbox, textarea, dropdown, etc. components and they can all add/remove their own questions from their own surveys. This can all be database driven to store the type of component, some unique name, and possible answers.
I would think most web programmers have done something like this or toyed with the idea. It's quite useful and not very complicated. You aren't rewriting a programming language. Instead of editing the code, typing a new question, creating a new <select> box, and adding a column to the database you can just have an admin page to update the database.
Admin
Come on, who can seriously deny that the code itself should act as the comments as much as possible?
Strange that such a comment would be posted.
Admin
Wow - where to start. An article that asserts that because something can be done in a stupid way it must be a stupid thing! If it was really easy to just change the code when the business rules changed, no IT department would have a maintenance backlog (and, in case Alex hasn't noticed, most do). Ask not if you can code it but if you should! Longer reponses on my ebizQ blog. JT www.edmblog.com
Admin
I'm a little surprised no one has brought up the Model-View-Controller methodology and the multitude of frameworks that use XML config files to establish that methodology. Personally I'm all for the separation of business logic, and have reaped the benefits numerous times when redeploying existing applications for businesses sharing few similarities. They typically merge both hard-coding and soft-coding techniques together quite nicely. For instance rather than defining DAYS_IN_WEEK, you would call a function to return that number for you, and the function that was called would be defined in the configuration file. This is handled quite nicely through event-based implicit invocation, a hallmark of several MVC-based frameworks.
An Introduction to Software Architecture
Admin
At work, we use a time tracking software in which a day has eight hours and a week has five days. In the previous version it was "one day = 24 hours" and "one week = 7 days" and it was unusable.
Admin
That's silly. You don't want to know about which state you're in at all. You want to know which states have some requirement that requires different business logic. So name the function after that requirement:
If a new state implements this law, you change the above method. If the forms required change, you implement change the below method:
and most likely you'll immediately want to write:
Admin
Who or what, by an act of legislature, must be paid on Tuesdays?
Admin
#define three 2 #include "parent"
There, I agree now.
Admin
I've worked in more than one industry in which code changes require a great deal of regulatory approval, but configuration changes don't. Part of the "Hard Coding" versus "Soft Coding" evaluation involves the consideration of those kind of constraints (or the lack thereof). So the "best" answer for the same functionality in different industries may be different, even if the language is the same.
Admin
This article really made me lose a lot of respect for Alex, and question the quality of the other writing on the site (which I've been reading for quite some time).
I'm sure it's often possible to get away with the sort of hackish, fast-but-crappy coding he promotes when it's internal to a company. It's still terrible.
End users of a program should never have to change the source code and recompile just because data (like which states require a particular form) has changed. Source code gets lost. If you buy a product, you probably don't even have the source code.
Oh, wait, maybe the end users should agree to disassemble and hex edit the program because that would save the developers from actually having to do their job and develop the program properly.
What a bunch of lazy, poor developers in this thread. If you want to be a crappy hack that writes unmaintainable code, at least have the decency to acknowledge it and use a scripting language instead so that people can clean up your mess when (not if) it becomes a problem.
Admin
And all of the ones still in use (I refuse to count the Discordian) have either no week at all or a 7-day week. The last one to survive more than a year that used any other week was the French Revolutionary.
Admin
Admin
The difference is that when the logic is encoded in a data file you are implicitly encouraging your customer to change that data file - so multiplying your testing by n.
Admin
I always felt that code should be something that looks nice, and not only to you, but to another developer. Not only that, it should do what it was meant to without kludge. There should be no excessive use of complex coding concepts when they are not needed. A lot of people want to flex their programming muscles, and therefore misuse code all over the place in order to feel superior and show off their elite knowledge. Soft coding is a wonderful example of that, but I can't say that I am exempt from misuse... It's a constant process trying to find a happy medium, or a constant process to understand the tools you have been dealt. With new development abilities on the rise (such as LINQ) people are bound to abuse and misuse, and to further progress ways of doing things efficiently and eloquently as well. I have a feeling we all generally end up on both ends of the stick!
In the end though, if I can't clearly communicate to another developer what my code is supposed to do, then I might of failed in the process of what I was trying to accomplish. I want to write something, that when read by another, they can relate.
And then the process of passing the torch becomes less painful. Frameworks, patterns, and the such help to eliminate it a little, I guess. But in the end, I think we want something that most eloquently states what we were trying to accomplish, and sometimes too much hardcoding can turn a good idea that might of made a good short story into a burdensome repetitive novel. Happy balance, hard to find.
Admin
oh, and business requirements. A lot boils down to business requirements.
Admin
Uh huh, if anything this post and it's comments prove that a lot of you need to be a bit more open minded, as half of you vigorously claim to have the one true answer and manage to be more righteous than the other half with the other one true answer.
Confucious says: be liberal in the input you accept and conservative in the output you emit.
Also, if you really have a way to know the "one true answer" for every situation regardless of exterior considerations then please write me a book, as I'm tired of weighing the endless number of contextual factors that go into producing this code crap.
Admin
As someone who both admins and codes, I find this article horrifying. It sounds like it was written by someone who has the luxury of writing code and not actually maintaining systems and code over the long term.
First off, making everything configurable should be really "cheap." Most languages have some sort of framework for making things easily configurable. Even if your language doesn't have such, you will have to develop one for the cases that are inarguably hardcoding. Once you have an infrastructure for easy configuration, it should be really cheap to make everything configurable.
Secondly, from a full lifecycle perspective, often the things that change are not the things that you anticipated upfront. The more things that are configurable, the easier it is to make changes during the lifecycle of the program. Sure, some changes will require a recompile, but by putting as much as is reasonable in a configuration file, you minimize this.
Also, as others have observed, in many environments, it's a lot easier to get permission to change a configuration than to change code. Code changes require careful testing, since coders tend to break things; config changes also require testing, but can be more easily backed out.
And also, "recompiling" is not always a simple matter. After N years, the compilers, tools, and platforms might themselves have changed, such that even recompiling original source might not produce new binaries that behave identically to the original binaries.
Admin
NUM_DAYS_IN_WEEK, ONE_MILLION, and NUM_SECONDS_IN_MINUTE will yield better results when grep'ed on as well as the first reply points out that it avoids typos and adds clarity to hard values.
Admin
Date/time arithmetic is merely the canonical example; the problem domain is widely recognised; there's the potential for lots of magic numbers (like 60, and 146097) that are either not obvious, or ambiguous; and calculations that it's easy to botch. Which is why there are libraries. Written by alien civilisations far superior to ours. Thank goodness we humans never have to write libraries.
Admin
Admin
1E06 = miljoen 1E09 = miljard 1E12 = biljoen 1E15 = biljard 1E18 = triljoen 1E21 = triljard etc
although such large numbers are not usually pronounced :-)
Admin
It doesn't matter where you start counting. Even if you start from 42, the number of days in a week will still be 7.
Admin
ok thats enough. To imagine that users of software cannot "change business rules" is just indicative of how out of touch Alex is with real use of real software. Alex is truly his own web page, "worse than failure."
Moron. And your forum software sucks.