-6

As an intermediate stage hard-coding is accepted by Google in their Tour of Heroes Angular tutorial but the benefit cannot surely only be for novices. Do people not understand that hard-coding as an intermediate step allows an additional stage of testing to be undertaken on highly scalable systems in a manner that removes outside services from the equation and/or helps isolate individual behaviours, or is there some hereforeto unconsidered problem?

Additionally, once a dynamic solution is in place, what can be wrong with embedding these values in the code, accessible via in-code boolean toggles or environment variables, as a fall-back when troubleshooting networking issues, security problems, or isolating a bug to a single service?

  • If you hard-code, the value cannot be changed by someone other than you (or a proxy for you that involves being able to legally and practically edit the source). The hard-coded part is no longer user extensible, and that's (IMHO) bad for a microservice. – Jared Smith Mar 27 '18 at 19:46
  • 8
    Can you describe more fully what you mean by "hard coding" and its alternative, and explain why the alternative precludes an additional stage of testing to be undertaken on highly scalable systems in a manner that removes outside services from the equation and/or helps isolate individual behaviours? – Robert Harvey Mar 27 '18 at 19:49
  • 1
    softwareengineering.stackexchange.com/questions/328007/… is the example of usage I was working from – Peter David Carter Mar 27 '18 at 19:50
  • 4
    @Jared: Some values won't ever need to be changed. Pi, for example. – Robert Harvey Mar 27 '18 at 19:55
  • 1
    @RobertHarvey I live in Indiana :) – Jared Smith Mar 27 '18 at 19:56
9

Hard coding isn't the real problem. If your problem doesn't need dynamic code then adding dynamic code isn't solving a problem.

However, problems themselves are dynamic and change over time. So it's not unusual to end up needing code to be dynamic.

The real issue is when you let knowledge spread into inappropriate places. If you think:

  • it's fine to hard code, so
  • it's fine to use a static solution, so
  • it's fine to spread references to static things to many places

well now you've now caused a problem. Because now switching to a dynamic solution is a huge pain.

The difference is subtle. Some refuse to ever work statically because it's so easy to slip. But it is knowledge, spread inappropriately, that causes the real problem. The more things that know about something the harder that something is to change. So long as a change can be made in one place hard or soft doesn't really matter.

As for testing. Just don't add it late. Putting off testing makes it more expensive and less useful. If you can test early and be static fine. For most though that's easier with dynamic solutions.

Dynamic solutions can solve static problems. Problems can become dynamic. A dynamic solution can make testing easier. But you don't get dynamic for free. It's work. Don't trust anyone that insists there is only one way. Find out for yourself what either will cost you.

  • 2
    That last paragraph earned you a +1 from me. – Robert Harvey Mar 27 '18 at 20:45
  • @RobertHarvey praise from Cesar. +1 to yours as well for insisting that we think about change. – candied_orange Mar 27 '18 at 21:01
  • Does a Junior dev's answer get a look in tho? – Peter David Carter Mar 27 '18 at 21:06
4

Hard coding should be reserved for invariants.

If you know that some data is very unlikely to change, you hard-code it.

const int numberOfStandardChessBoardSquares = 64;

For everything else, there's configurations.

There are compelling reasons to hard-code things. You would not compute Pi each time you need it, because that computation is expensive. Rather, you decide what resolution you want, and code a constant:

const double pi == 3.1415926535897;

If you stand up a complex system that requires some kind of diagnostic mode, it can be handy to have some sort of data pattern hard-coded into the production code so that you can transmit data across your system with a known fingerprint. You don't want this kind of data in a configuration file that's subject to tampering, and in the unlikely event that the baseline data pattern needs to be changed, one would simply deploy a new production version.

In the absence of the need for such a diagnostic mode, test data of this kind is better kept in a test harness or test assembly, where it can be cut away from the production executables prior to deployment.

2

Do people not understand that hard-coding as an intermediate step allows an additional stage of testing to be undertaken on highly scalable systems in a manner that removes outside services from the equation and/or helps isolate individual behaviours, or is there some hereforeto unconsidered problem?

What?

No, hard coding is a code smell, full stop.

If anything, doing so in microservices is extra troublesome because microservices will tend to need more configurability because

  1. There's rarely ever one instance. Hard coding to one instance will fail once you have two instances/targets/databases/whatever.
  2. There's rarely ever one locale. As soon as you hardcode strings/timezones, things will break once you deploy to that other region.
  3. There's rarely ever one host. Containers can kinda mitigate this, but as soon as you hardcode some file path or make assumptions about your OS, it'll fail when you switch containers or web servers or OSes or...

But like all code smells - sometimes you follow the smell and end up somewhere that isn't terrible. Sometimes a simple hardcoded value has very little downside. Sometimes it can provide something that can't possibly go wrong. Sometimes it's in a spot that would need to be destroyed entirely if the assumption of the hard-coded value changes.

Though usually it's just people being lazy.

  • I was talking about hard coding as an intermediate stage that persists in the debug area of the code, as specified. Your answer might be thought of as 'correct' but it doesn't address the problem. – Peter David Carter Mar 27 '18 at 19:57
  • @PeterDavidCarter: Oh, I get it now. You're talking about "Test data in debug build configuration," right? – Robert Harvey Mar 27 '18 at 19:59
  • 1
    Contrast that with the original system it replaced, which stored configurations in the database directly (the very definition of "soft-coding"), but was so complicated that it took 3 to 5 times the effort (and 10 to 20 times the code, in the form of setup scripts) to stand up a new service. – Robert Harvey Mar 27 '18 at 20:05
  • 2
    All that said, I don't see anything wrong with providing hard-coded test data that can be configuration-switched, but isn't that sort of the role of a test project/test suite? I find it distinctly uncomfortable to litter production code with #if DEBUG statements and test data when I know I could have sequestered that hard-coded test data in a test assembly, where it belongs. Unless, of course, there is some distinct advantage to having a diagnostic mode in your production system. – Robert Harvey Mar 27 '18 at 20:11
  • 1
    @PeterDavidCarter - I wouldn't consider mocked data/services to be hardcoding. – Telastyn Mar 27 '18 at 20:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.