Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Here on PM get() and set() methods seem to be pretty commonly advocated for. I think there are some pretty good reasons why their overuse should be avoided in object oriented designs. The primary problem with them is that they can defeat the data encapsulation principle of OO design.

Here is a simple example:

package OOtest; sub new { my $invoker = shift; my $class = ref($invoker) || $invoker; my $self = {}; bless ($self, $class); $self->{list} = []; return $self; } sub get_list { my $self = shift; return $self->{list}; }

Later on we use the accessor:

my $obj = OOtest->new(); foreach my $tmp ( @{ $obj->get_list() } ) { # process list }

If we later decide to change the implementation of our list to a hash our loop will also process the hash keys (this would most likely not be what we want). We have to change code outside our object to conform with the new internal data structure of the object. The accessor method is breaking our data encapsulation. set() methods are especially vulnerable to this.

Accessor methods should be used cautiously and only when unavoidable. Instead of using accessor methods write methods that provide "behaviours" for your objects. This moves more code into your objects but provides much better data encapsulation. Then making changes to your object's should only require you to change code inside you object.

UPDATE: I agree this example is pretty flimsy. But I wanted an example that didn't require to much explanation. A better example might be an accessor that returns a hash generated by an internal sub. Bugs or changes in the hash generating sub could affect code outside of the object. The point I was trying to emphasize is the fact that a connection exists between code outside of your object and the internal data representation. The accessor methods are what create this undesirable dependancy.
I also corrected a typo in the example.

UPDATE: After looking at this meditation again and thinking about some of the great comments, I agree with some of the other monks that the tone this node takes is a little too harsh. I primarily wanted to give a warning for people new to OO. The "make an object by just giving it a bunch of public accessors" approach seems to be a common mistake. However, there are good reasons for using them sometimes. And when you do use them realize that they are a major portion of your object's interface.

A lot more has been written about this elsewhere:
"Why getter and setter methods are evil".

Another way out of this hole is to return whole objects:
"Return New Objects From Accessor Methods"

Both links are Java articles but the design issues are universal.

In reply to Why get() and set() accessor methods are evil by synistar

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (3)
As of 2022-12-09 13:23 GMT
Find Nodes?
    Voting Booth?

    No recent polls found