• Prime Mover (unregistered)

    If that's the reaction of everybody at that place of work in response to a tedious but procedurally necessary task, no wonder the project got shelved.

  • TopTension (unregistered)

    The point of trivial setters and getters is that you can add more complex logic, validation and what not later on without having to find and modify gazillions of direct accesses.

  • (nodebb)

    That's why people should prefix their private variables with underscores. It helps to differentiate between the class-level _x and the parameter x. But I guess TRWTF (again) is Java Beans. OOP without encapsulation defeats the whole purpose.

  • Naomi (unregistered)

    FWIW, while I don't entirely disagree with you about trivial getters and setters, they can be really useful as a refactoring aid. My day job deals with reviews, and for a long time, reviews had "tags", modeled as a simple Set<String>. We later wanted to change this to a more sophisticated model, where a review could mention all sorts of things - topics, people, organizations, dates, etc. - where "tags" would now correspond to "topic mentions". The problem is that getTags and setTags were used extensively throughout our code base, so we couldn't trivially remove them. Instead, we replaced them with non-trivial methods that get or set the topic mentions, ignoring all the others. Since our JSON serialization framework (Jackson, for the curious) uses the getters and setters, it didn't even have any impact on third-party applications using our API, although we do encourage them to look at the new mentions field instead. None of that would have worked with direct field access.

    As for boilerplate, I don't think that has to be a big problem. Java has Lombok, C# has property notation, both languages have record types, and I'd be surprised if C++ doesn't have some template solution, probably in Boost.

  • TheCPUWizard (unregistered)

    One reason for "boiler plate" setters is that t keeps the context the same from a caller perspective, even at the binary level. This is important if one wants to be able to update the target (implementation) without updating that invocation (caller).

  • Naomi (unregistered)

    But I guess TRWTF (again) is Java Beans. OOP without encapsulation defeats the whole purpose.

    This was posted while I was writing my other comment. Depending on context, "beans" are either Java's equivalent of structs (simple containers for closely related data), or a specification that allows reflective libraries to play nicely together even if they're written by unrelated people. Neither meaning has any relationship to someone accidentally writing a useless method, nor is that in any way a Java-specific problem. No one would be blaming the language if someone committed a comparable mistake in C#.

  • LZ79LRU (unregistered) in reply to colejohnson66

    This is why I like the Properties from C#. For those that don't know Properties are a way to blur the line between a field and a getter/setter pair. As far as the code writer is concerned they are called as if they were fields. And yet they conceal a getter and setter inside, optionally.

    So if you want to have a field you just make a field. You need to change a logic and now you need a getter or setter? Just append { get {...} set {...} } in your class to that field and change no code anywhere else.

    And best of all, properties also allow for other neat tricks such as asymmetric access rights. As in object myField { public get; protected set; } means myField can be read by anyone but only assigned a new value by my class. Which is super handy.

    It's one of he things I wish other languages, especially C++ would copy from C#.

  • (author) in reply to TopTension

    This is a thing that rarely happens, but also, complicated mutations should probably be represented by objects anyway, so you wouldn't want a setter in the first place. The solution to pretty much any problem in OO is to throw an object at it.

  • Barry Margolin (github) in reply to LZ79LRU

    Python and JavaScript also have properties similar to C#, although the definition syntaxes are different.

    In languages without properties, the usual approach is to just declare all fields private and have a convention that all access to fields is done through getX and setX methods. That's the approach Java has taken.

  • Rob (unregistered) in reply to colejohnson66

    That's why people should prefix their private variables with underscores. It helps to differentiate between the class-level _x and the parameter x.

    That's what static code analysis and IDE warning reporting can help you prevent. If I do stuff like this, my IDE already starts complaining, and if things sneak through then SonarQube will complain some more.

  • iWantToKeepAnon (unregistered)

    I hate getters and setters too, it is lazy programming and bad oo design. Like it was said, it does nothing to encapsulate the properties. E.g.

    double getAmount() {}
    void setAmount(double a) {}
    

    You've just exposed a field AND its type. What if you want to change it to integer? Code is broken. What if you want to store an amount and a tax value? Encapsulation means you can do that behind the scenes w/o the caller knowing what is going on. But w/ getters and setters you must expose both those fields. Basically you're letting the caller implement your business logic/technical details. Blech.

  • (nodebb)

    There's nothing in OOP that says you have to have getters and setters for every single member variable. However my experience is that it better not to have public member variables and instead use getters and / or setters as applicable.

    public member variables are a disaster waiting to happen in my experience.

    Addendum 2023-07-25 16:41: addendum - getters and/or setters as applicable, or indeed no external access at all.

  • Anon55 (unregistered)

    Why on earth is regression test required to remove dead code?

  • (nodebb)

    We also need to distinguish between "external" state and "internal" state. Internal state is, in essence, an implementation detail of the class, and fields containing internal state must never be exposed in any way, i.e. it must be stored in private fields with neither getter nor setter functions.

    External state is the stuff that someone outside might be interested in, like e.g. the name field(s) of an employee record class. That class (even if it probably shouldn't exist as such) might be able to justify getters for those fields, but in general, even external state should not have trivial setter functions. At the very least, those functions should block updates that don't make sense (and throw exceptions!), and do any cascading updates that are necessary, stuff like that.

    A saner example of what might look like a "getter" lives in a class that I'll call AveragingAccumulator. It's a container for (numeric) values, and you feed it new values over a time period or whatever, and it then has "getter" functions that can return the mean, the mode, the median, the standard deviation, and even just the number of accumulated values. (But I'd call those functions things like mean(), mode(), median() and so on, rather than get_mean(), get_mode(), get_median() and so on.)

  • (nodebb)

    We also need to distinguish between "external" state and "internal" state. Internal state is, in essence, an implementation detail of the class, and fields containing internal state must never be exposed in any way, i.e. it must be stored in private fields with neither getter nor setter functions.

    External state is the stuff that someone outside might be interested in, like e.g. the name field(s) of an employee record class. That class (even if it probably shouldn't exist as such) might be able to justify getters for those fields, but in general, even external state should not have trivial setter functions. At the very least, those functions should block updates that don't make sense (and throw exceptions!), and do any cascading updates that are necessary, stuff like that.

    A saner example of what might look like a "getter" lives in a class that I'll call AveragingAccumulator. It's a container for (numeric) values, and you feed it new values over a time period or whatever, and it then has "getter" functions that can return the mean, the mode, the median, the standard deviation, and even just the number of accumulated values. (But I'd call those functions things like mean(), mode(), median() and so on, rather than get_mean(), get_mode(), get_median() and so on.)

    Addendum 2023-07-25 17:35: Bah Bah,, stupid stupid double double posting posting bug bug..

  • Duke of New York (unregistered)

    Just as goto is useful for going somewhere, a setter is useful when you want to set something.

  • xtal256 (unregistered)

    "They're often trivial boilerplate (boilerplate is a code smell), or they're hiding behavior where behavior probably doesn't belong."

    But hiding behaviour is what they are for. The public methods of an object are it's interface. If you put complicated behaviour where it doesn't belong that I think that's your fault not the language (although a good language should make it easy to do the right thing).

  • Gonzo (unregistered) in reply to TopTension

    without having to find and modify gazillions of direct accesses

    While that is a fair point, I wonder how often that really happens afterwards. Meanwhile best practices (and their religious followers) dictate to use that boilerplate everywhere.

  • LZ79LRU (unregistered) in reply to Gonzo

    More often than you'd think. Typically it is a result of writing code that thinks input is going to be sane (or like, validated by someone else) only to later discover that you actually need validation right there and than.

  • FTB (unregistered) in reply to colejohnson66

    Um, no. Prefixing variables with leading underscores is verboten in C++.

  • Gonzo (unregistered) in reply to LZ79LRU

    Yeah, sure that will be the main reason, but in my experience of 30 years in that business, one typically (not always) knows that in advance.

    For that reason I argue the sectlike getter dogma satisfies more the overengineering trends than actual business cases.

    Of course there are exceptions to the rule.

  • LZ79LRU (unregistered) in reply to Gonzo

    That only means that when it does happen it's going to happen at the worst possible time and under the worst possible condition. Like for example your boss that knows just enough about coding to be annoying deciding that the 10 year old class written by someone you newer met can be reused to service one or more new systems that didn't exist back than but have since been bloated on to the project and which don't have proper validation.

    That's why I like properties. Zero hassle refactoring. None of that Java style getter and setter #%$*.

  • Gonzo (unregistered)

    Agreed, that .NET found an elegant solution to that.

    My point however is rather that the getter topic in Java is often too dogmatic. Getters may be useful at times, but not always.

  • LZ79LRU (unregistered) in reply to Gonzo

    i absolutely agree. Java is a language originally developed with the idea that if you made a tool blunt enough that half trained craftsmen won't cut them self you can use numbers of cheap beginners to replace skilled developers. Turns out you can't. But the mindset behind it is still embedded in the language and any tutorial or example you find for it. So you end up with a whole lot of dogmatic rules that boil down to "just do this and don't think too much". Anyone remember design patterns?

  • TheCPUWizard (unregistered) in reply to LZ79LRU

    "So if you want to have a field you just make a field. You need to change a logic and now you need a getter or setter? Just append { get {...} set {...} } in your class to that field and change no code anywhere else."

    NOPE...... Write code with a public field... compile to DLL... Now someone else writes an EXE linked against that DLL.... Update the source to use a property, create a new DLL and distribute that...

    The EXE that was previously working was just completely broken...

    START with "public type prop {get; set;} " -- Now feel free to change the implemention without breaking existing consumers....

  • Duke of New York (unregistered)

    Sounds like someone really misses the good old days before garbage collection, unit testing and doctors washing their hands.

  • Balor64 (unregistered) in reply to TopTension

    If that ever becomes necessary, you can have Eclipse find all of those usages and automatically replace them with getters and setters. There are probably other tools that could do it too, if you don't like Eclipse. Bloating all your classes with boilerplate code because it might save you a couple minutes someday just isn't worth it.

  • LZ79LRU (unregistered) in reply to TheCPUWizard

    Good point. I am far too used to working with big projects that are all in house and are compiled together. Thank you for pointing that out.

  • (nodebb) in reply to Anon55

    Because you never really know! Once you're surprised enough times, it becomes habit to make sure not to just change stuff While You're At It unless the area is going to at least get a sanity check before it goes to production.

  • xorium (unregistered)

    The "setter" here presented is not a decent setter method at all as it has no parameter. Typically that parameter would also be called "status" and then it would have been a correct setter. Maybe someone removed the parameter but I cannot think of any reason for it.

  • Neveranull (unregistered)
    Comment held for moderation.
  • Gearhead (unregistered) in reply to FTB
    Comment held for moderation.

Leave a comment on “The Set Up”

Log In or post as a guest

Replying to comment #:

« Return to Article