-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
  • @JaredSmith in the enterprise environment you worked in, was that the case? I have not seen this definition myself. In my work place hard-coded was used to mean that feature branch code with in repo data was not to be pushed to develop or considered part of a complete Agile story. – Peter David Carter Mar 27 '18 at 19:47
  • 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
    https://softwareengineering.stackexchange.com/questions/328007/are-there-advantages-to-hard-coding-data-values-into-a-program is the example of usage I was working from – Peter David Carter Mar 27 '18 at 19:50
  • What sort of values are being hard-coded into the Tour of Heroes Angular tutorial as an intermediate stage? – Robert Harvey Mar 27 '18 at 19:53
  • @PeterDavidCarter I did not think my comment odd or obtuse: if you explicitly define a data value in source code with no mechanism (e.g. a setter) to change it, then you can't change it without changing the source code. Maybe that's what you want: but people are mistaken about that often enough to earn it the status of code smell. – Jared Smith Mar 27 '18 at 19:54
  • https://angular.io/tutorial/toh-pt2 – Peter David Carter Mar 27 '18 at 19:55
  • 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](https://en.wikipedia.org/wiki/Indiana_Pi_Bill) :) – Jared Smith Mar 27 '18 at 19:56
  • @PeterDavidCarter: OK. Which values on that page that are hard-coded would otherwise be "soft-coded" by those people who do not understand the benefits of hard-coding? – Robert Harvey Mar 27 '18 at 19:57
  • Do you mean hardcoding as a named constant in code, or as an inlined value in every place it's used? – CodesInChaos Mar 27 '18 at 20:13

3 Answers3

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.

candied_orange
  • 102,279
  • 24
  • 197
  • 315
5

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.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
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.

Telastyn
  • 108,850
  • 29
  • 239
  • 365
  • 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
  • @PeterDavidCarter no it's still bad. What if your testing/debugging needs change? – Jared Smith Mar 27 '18 at 19:59
  • @RobertHarvey that's one aspect, yes. – Peter David Carter Mar 27 '18 at 19:59
  • What are the other aspects? – Robert Harvey Mar 27 '18 at 20:00
  • Skipping the hard coding stage makes testing far less reliable and isolation of bugs less exact. You can never get away from that fact. – Peter David Carter Mar 27 '18 at 20:03
  • @PeterDavidCarter: I'm asking these questions because I'm not convinced that you've formulated a complete question. Consider an agent-model system that hard-codes business rules for a rules engine via Expression Trees, but because the code is stored in a database and compiled on-the-fly, it's actually a form of "soft coding." – Robert Harvey Mar 27 '18 at 20:04
  • 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
  • So I don't think your binary choice is nearly as clear cut as it seems at first glance. – Robert Harvey Mar 27 '18 at 20:07
  • 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