• (nodebb)

    So, a mis-named code-free God Object ? Ouch.

  • (nodebb)

    What is constant is the tendency of mankind to produce horrible computer programs.

  • Steve (unregistered)

    Go on, I'll bite / stick my head above the parapet -

    What's wrong with defining all your constants in one reference class?

    Repeatedly redefining or updating a constant I get the WTFery of (that ain't no constant, that's a session variable or a database increment or ...)

    But to my mind it's better to have all your genuine constants defined in one place, so everyone knows where they sit, everyone adds their new constant to the same place and maybe even adopts some form of unified naming convention, and you don't end up with two coders both defining their own NumberOfFlanges constant in different places to create a race condition as to which gets defined first.

    So what am I missing?

  • RLB (unregistered)

    As the old joke goes: constants aren't; variables don't.

  • (author) in reply to Steve

    Now, I wouldn't call "one class holding all the constants" a WTF or even a terrible idea, but I generally don't like organizing information based on traits like "immutable". And sure, distributing key information can bring other challenges, but I'd like to point out that even when you put them all in the same namespace, it doesn't mean that you won't end up with NumberOfFlanges and FlangeCount, and nFlange getting created. Plus, if you have a lot of constants, finding the one you need in that one big pile can be harder than you'd expect.

    To put it a different way: data should exist at the level where it's being consumed.

    I think what we see here- a global object getting misused- is the kind of thing that arises as a consequence of having that kind of global, used-everywhere structure in the first place. "Gee, it'd be a lot of work to set up a message passing system that gets the count of POs back to this module over here, but I can get the feature built quick and easy with this one easy trick that's not technically a global variable…"

  • (nodebb) in reply to Remy Porter

    I think what we see here- a global object getting misused

    I concur and would like to add an example to help with understanding...

    Constants.PI is functional. Math.PI is functional, descriptive, discoverable, and more easily packagable. By the last comment, I mean that the question "who is responsible for the package this lives in" has a much better answer and that package's source control history will make much more sense.

    Addendum 2021-04-15 08:15: I hate this editor.

  • (nodebb)

    We should probably also find out whether this class called Constants is at the global-namespace level, or whether its "true" name is CompanyName.Application.FunctionalArea.Constants.

    If it's at the global level, the right tool for correcting it is a GAU-8 (come on, y'all keep one handy in your back pocket, right?) applied to the guilty' party's head.

    If it's at the company+application+functional-area level (containing only constants for that particular functional area), it's unfortunate, but not catastrophic. It would be better to move most of them into more specific classes, but OK.

  • Anon (unregistered)

    So are we just going to not talk about how poNumber is a string?

  • John (unregistered)

    My guess it that "constants" is a misnamed "settings" or "configuration", etc.

  • (author) in reply to Anon

    That's not uncommon. PO Numbers are often something like "SBU-100-9514-PAINT"

  • (nodebb) in reply to Steve

    Unlike Remy, I would consider placing all constants in one place a very strong anti-pattern. Consider if this was C++... Adding one constant could trigger a massive re-compile at the very least. Also, it becomes increasingly difficult to have short meaningful, non-ambiguous names...

  • Loren Pechtel (unregistered)

    I can see a problem with having a bunch of constants in a pile because of recompiling issues, but it strikes me as quite practical to have a pseudo-god object with all the information you read from your configuration files. If you also need a bunch of constants define them as readonly variables in that same collection.

    Now, lumping variables in there also is wrong.

  • (nodebb) in reply to Loren Pechtel

    a pseudo-god object with all the information you read from your configuration files

    That's not a pseudo-god object, that's a single purpose object whose only responsibility is providing configuration data.

    Seeing '''Configuration.BackupPath''' somewhere in the code not only tells you it's the place where backups go, but also that it's one of the configurable parts of the application.

  • MiserableOldGit (unregistered)

    If it's a constant with only some local relevance then stick it there, if it has a global significance then put it in a central collection and name and comment it properly.

    But this is not a constant, it's not even a global variable, it's a function hiding in a property getter, concealed in a list of global constants. And I'd hazard a guess the problem is bigger. ERPs are never the smooth end to end best of breed solution they are marketed as, always a Frankenstein monster of ill-fitting applications scruffily welded on to whatever legacy systems and industry specific necessities this client has .. that PO number generator is hiding a world of pain.

  • Gerry (unregistered) in reply to Anon

    Rule of thumb. If you aren't going to perform maths on it, use a string. Otherwise someone will have a really good reason you need to have leading zeroes, or spaces, or hyphens....

  • (nodebb)

    "That ERP system was developed by whatever warm bodies happened to be handy, which meant the last 'tech lead' was a junior developer who had no supervision, and before that it was a temp who was only budgeted to spend 2 hours a week on that project."

    Sounds like that place could do with a good ERP.

  • 516052 (unregistered) in reply to Steve

    Nothing, untill you open up the file and realize its several thousands lines deep. And than you cry. Or you give up and add your own to the list without reading it all.

  • WTFGuy (unregistered)

    @Watson ref:

    Sounds like that place could do with a good ERP.

    As in "Extreme Restructuring, Pyrotechnic". IOW blow it up good. ;)

  • Dave (unregistered) in reply to Anon

    Things colloquially referred to as numbers - such as phone numbers - are often actually strings of numeric characters.

  • (author) in reply to Dave

    Dave, I like to call those things "digit-strings".

  • (nodebb) in reply to Gerry

    That's not a good rule. Table id columns are always integer, yet you don't do math on those. When it comes to customer facing "numbers" like PO number, I'd argue it's preferable to use integers over strings: numbers are more international, no need to worry about users with non Latin based languages; they're faster to query in customer request scenarios. I do acknowledge that letters increase the range of possible values greatly, which may be a necessary consideration in some scenarios.

  • DanK (unregistered) in reply to Mr. TA

    ...and that's why ZIP codes that start with 0 often fail to validate or get printed incorrectly. A string of numeric characters is not the same as a number.

  • Nel (unregistered) in reply to Steve

    I've seen this approach a few times and it wasn't so bad until I joined that project with a huge Constants class with hundreds of constants shared among different applications, including every possible log message as they expected to use this for localization too.

  • MiserableOldGit (unregistered) in reply to DanK

    That type of example should be fixed with formatting. People converting integers into strings for reasons like that deserve their own circle in hell.

    I once "inherited" a system where all the receipt numbers were hard-coded as fixed 6 character strings, complete with an unreliable approach to perform maths on them. It didn't just convert them into integers and do normal maths and convert them back, no, this thing recreated maths at character level like some kind of ascii abacus. It hadn't even been done in a repeatable way, various slightly differing implementations of this approach were sprinkled across myriad functions. These "receipt" numbers were actually at line item level, so we did have to do proper maths on them to determine things like number of items in the sale, and which product groups they belonged to, so when it was wrong all hell broke loose. But because the code in the salesmens' handsets was the cause of this chaos (and so, a pile of WTF I never really began to comprehend) the incrementer would forever reset midday creating orphaned transactions that had to be traced by hand. I threw the towel in on that one after six months, I made the wrong decision at the start trying to work with it and improve it rather than present a case to rip the shit out and recode it properly.

  • (nodebb) in reply to DanK

    While US zip codes are numeric, international postal codes often have letters. So this is a case where we the software industry have to represent what's already present in reality. But even ignoring the letters in other countries, errors caused by zip codes starting with 0 are bugs in the software, not a problem with using integers for zip codes.

  • WTFGuy (unregistered)

    The fact a tremendous amount of our apps now use JSON or SOAP or SQL commands as built-up strings or ... as the transmission medium / glue between disparate systems means everything gets round tripped to/from strings anyhow. Plus it's a fact that so much code is written in untyped or weakly-typed glorified scripting languages.

    Doesn't mean we shouldn't try to use strong and appropriate data typing where we can. But it sure explains how folks raised in this "everything's a string at least sometimes" world would readily fall into writing stringly solutions to non-stringly problems.

Leave a comment on “Constantly Counting”

Log In or post as a guest

Replying to comment #:

« Return to Article