Re: Re: Re: Re: Re: Item 42: Don’t give away your internals… ;-)

Hi Atul,

I checked your references and now I feel I can provide an adequate reply ;-). To be honest, this was the first time I heard that having setters/getters is bad design and your quote from Stroustrup shocked me at first because I thought that I already knew a bit about OO design ;-).

To summarize, having too many setters/getters might be a symptom for bad design because this kind of interface calls for other objects to work on the object instead of designing the class to do the work internally.

Here is a quote from your last reference which illustrates the controversy quite nicely:

“Nonsense,” the Guru said definitely. “They are frequently overused instead of providing a more appropriate abstraction, that is true. Getters and setters are better than public member variables, and they are worse than a better abstraction if a more appropriate and high-level one exists. But getters and setters can nevertheless be a good abstraction.

Also reading a bit further in the message you linked to at Google groups:


Generally, such classes are maintained by some sort of dedicated collection or manager. Such classes are, however, usually pure data; true behavior and business logic are situated elsewhere (and generally depend on more than one object of this sort).

IMHO, depending on the applications, setters and getters may be perfectly appropriate for this second category. In other applications, just using a struct may be even more appropriate.

I have to admit I have fooled myself into thinking that classes with setters/getters are always better than good old structs. One example in Calitko where I chose the struct anyway is Gnutella::NodeInfo. Honestly, the only reason I made it struct was because I was too lazy to write all the setters and getters for each member. Now I realize why that was a good decision ;-)

Now let’s analyze whether NodeAddress deserves to be a class and whether the setters/getters are really necessary. Here is part of the class description:

“A NodeAddress object can store host name or a host address (IP) and a port. If the host name is set, then the IP address is null. If the IP address is set, then the hostname is null. The Connection classes would know what to do in each case.”

From this description follows that NodeAddress does more than just store an address with port. It stores either an IP address with a port or a hostname with port. toString() works correctly in both cases and the object can be initialized from different values. The setters and getters are provided to access the data fields (object properties). NodeAddress is therefore more data with less behavior and IMHO it’s a nice class and setters/getters are not much of a problem. A further reason to “vote” for the class is that we might want to implement reference counting on the private data and we can’t do that in a struct.

I think there might be places in Calitko where a struct would be more suitable than a class and after this discussion I would be more confident about choosing the struct ;-)

Please let me know what you think!

Best regards,

Peter

Would you like to post a relpy?


This post is a reply to:
Re: Re: Re: Re: Item 42: Don’t give away your internals… ;-)
Dear Peter I think we are discussing two different things here... 1. The violation of Item 42 -- this applies to, for example, Pong::port, Pong::setPort, Pong::ipAddress, Pong::setIpAddress, Packet::setTtl, Packet::ttl, NodeAddress::hostName, NodeAddress::setHostName etc... And 2. (more...)

No follow-ups yet.