in reply to Are lvalue methods (as properties) a good idea?

Getters/setters break encapsulation, so if you are never trying to do the equivalent of overriding = to call additional code, you might as well be saying $object->{digits}=123 for that matter... If the module allows overriding of property methods on a case by case basis, then good for it...
  • Comment on Re: Are lvalue methods (as properties) a good idea?

Replies are listed 'Best First'.
Re^2: Are lvalue methods (as properties) a good idea?
by Ovid (Cardinal) on Jan 12, 2005 at 21:45 UTC

    I hear this quite a bit but I never see anyone provide concrete references that really explain why getters and setters are such a horrible thing. I would really love to see more information on this.

    Cheers,
    Ovid

    New address of my CGI Course.

      Nothing wrong with doing them if you think it all through. But blindly providing getters and setters for all your member variables means you've published your invidual attributes as a public interface for your object, which means that any new version of your object has to support at least that specific interface.

      Your public interface should be carefully considered. If some parts of that interface map into a simple setter or getter, fine, do it. But don't do it blindly.

      -- Randal L. Schwartz, Perl hacker
      Be sure to read my standard disclaimer if this is a reply.

        That sounds perfectly reasonable and is the best defense I've heard of the Anonymous Monk's assertion. However, I have heard (more than once) comments which suggest that all getters and setters violate encapsulation. Such blanket assertions usually make me very suspicious as to whether or not the person making the statement has really thought things through. Dogma scares me.

        Cheers,
        Ovid

        New address of my CGI Course.

      It's not the getters and setters that ar bad, but using them to upset Mr Demeter.

      See also: Re^4: Law of Demeter and Class::DBI

      IMHO the Law of Demeter isn't like the speed of light, but it's a pretty good heuristic for OO design.

      /J

        I tried to find a concise explanation of the Law of Demeter, and my brain melted.

        The best I could find was wikipedia's entry on law of demeter.

        "More formally, the Law of Demeter for functions requires that a method called from an object may only invoke the methods of the following kinds of objects:
        1. itself
        2. its parameters
        3. any objects it creates/instantiates
        4. its direct component objects
        In particular, an object should avoid invoking methods of a member object returned by another method."

        There is TONS written about LoD when googled, but nothing that gave me a real "aha" feeling. It all left me wondering, is this real insight, or cargo cult programming?

        Hopefully the above definition will help a bit.

        thomas.

      I never see anyone provide concrete references that really explain why getters and setters are such a horrible thing

      Yes, I dislike emotional words like horrible and evil; writers employ these words as attention grabbers. As merlyn explains nicely, they are not always horrible or evil ... but can be if used unwisely. As usual, there are tradeoffs involved and mindless slogans cannot replace sound judgement, experience and good taste.

      A couple of general references that discuss this are:

      Allen Holub JavaWorld article Why getters/setters are evil
      AccessorsAreEvil
      TellDontAsk

        That javaworld article just seems to be saying that if a field should not be accessible outside the object then adding setters and getters is a bad idea. Of course it is, if people are doing this then they're very very silly.

        He doesn't seem to address what, for me, is the main reason to use setters/getters, that is add even more encapsualtion and hiding by protecting the user of the object from it's internal representation. As far as I can tell from the article, he thinks raw field access is OK if the fields are part of the public interface. This causes plenty of problems too when you want to change the internal representation of the object's data. If you have lots of code that goes poking around inside the fields directly then all that code will break if you want to change a field.

        This is a similar sin to the one he's trying to avoid. They both come from including things in the public interface that are not necessary and which could change in the future.

        The "answer" for me is that fields should never be part of the public interface and for those fields that need to be accessed from outside, you should write public getters/setters so that if those fields ever change their meaning or you change your object from using x,y coordinates to using r, theta then you just have to rewrite getX, setX, getY and setY and all your old code will still work.

        Having said that some languages (Perl with lvalue methods, Object Pascal with properties) allow you to have fields that seem to be normal fields but actually they result in a call to a getter/setter method. This to me seems to be the ideal solution. For example in Object Pascal when you write object.Field = 5 you don't know whether that will directly write to memory or whether it will call object.setField(5). What's great here is that the user of a class doesn't need to deal with setters and getters but the implementor get all the advantages that they bring.

        Finally he uses the example of getX where the return value changes from an integer to a double and he says that all the code that uses getX will need to change to cope with that. Perfectly true but I don't see how you can blame that on getX. If, instead, you access the X field directly then you're still going to need to change all your code. Seems like a silly example to me.