1. 14
  1.  

  2. 6

    A super rough rule of thumb: use getters if you need to perform logic to determine the property. Use setters if you need to maintain a class invariant. Otherwise use direct access.

    1. 8

      Always using methods for access is a type of future proofing since you can never be sure when you may need to add logic around access, and so a method is more tolerant of change over time. The interface changes if you switch from property access to method access in Java.

      I have no strong opinion, though, since I see it as a judgement call.

      1. 8

        My question is how often has the working programmer ever had to do that? I don’t remember ever doing this in all my years of software. Not once have I been able to take advantage of the fake insurance policy that getters and setters provide.

        Well, I have had to do it before. Maybe the author writes more green field stuff than maintaining systems.

        1. 2

          In most cases, you’ve got the source code that uses the object. Just change the code.

          1. 1

            Less-helpful for writing libraries used by several code bases - also something I have done several times. This is why it’s a judgement call to me. You are in a better place to predict how your code will be used than I am.

      2. 5

        I try to avoid public fields, as they (a) weaken encapsulation and (b) over-complicate APIs. Whenever I find myself thinking “should this be a field or a method?”, I choose a method, since methods have more calculation power and also prevent exposing internals to mutation. The same goes for “properties” (e.g. in Python): just use methods.

        I try to avoid setters, and mutability in general, in favour of returning new instances (with different constructor arguments).

        Whilst I’ve got nothing against “getters”, I do try to avoid the word “get”, since it’s association with “getters/setters” has two bad habits: overly exposing our internals by default, and strongly coupling our API to our implementation.

        Rather than “getting the foo field”, I try to choose API functions without thinking about what the private fields/methods/etc. are.

        1. 3

          Worth reading after you get past the click-bait title and the knee-jerk response. But… if you can get past those things you probably don’t need the advice in this article.

          1. 2

            Another approach is to do neither and avoid exposing properties at all, especially ones where you’re just getting another object to operate on (i.e. Law of Demeter). The pattern was written up as Tell Don’t Ask at https://pragprog.com/articles/tell-dont-ask

            1. 2

              The absolute worst part of this is that this code is generated boilerplate that is present everywhere in the language. I find the same thing is present in PHP. At least in ObjC, there’s sugar in the language.

              And maybe higher level languages are following the wrong OO model, because I feel there’s very little to gain from distinguishing between properties and methods there. Message-passing OO is much simpler.

              1. 1

                Yet another approach is not to use setters that actually modify the object, but return a new modified object:

                public class Person {
                  private String name;
                
                  public String getName() {
                    return name;
                  }
                  public Person setName() {
                    Person p = new Person();
                    p.name = name;
                    return p;
                  }
                }
                

                (It’s non-idiomatic, terribly verbose and there is probably a much better way to implement this, but you get the idea: immutability.)

                1. 1

                  I’d say generate getters and setters everywhere if one really only uses objects as data or modular containers. On the other hand, if you model your problem domain based on encapsulated objects that expose domain behavior - then don’t. The former maps to modeling the concepts in your domain within your data model, which is so prevalent today.