Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re: The Accessor Heresy

by radiantmatrix (Parson)
on Nov 28, 2005 at 22:41 UTC ( [id://512420]=note: print w/replies, xml ) Need Help??


in reply to The Accessor Heresy

I think you might be over-thinking the nature of objects. I agree that working with object properties using set/get pairs is a bit of laziness; sometimes laziness is good, but I do think the meme is over-used.

Having thought about your Circle class (and ignoring all the proper inheritance tree that should really exist, etc.), I've come up with my own to illustrate what I'm about to attempt explaining.

To me, an object is a set of data (attributes) that can be acted upon. When I design an object class, I try to think about what data is really an attribute of the object I'm representing, what can be derived (and/or normalized), and how I'm going to act on that data. The interface should focus heavily on the latter: actions performed on the object's data. The data should be as hidden as possible.

In the case of our simple conception of a Circle, we only really need to store one attribute, since the other things we're interested in can be derived from it. I chose the radius, since that seems to make sense to me. When we create a new instance of Circle, we know at least one property of that circle, so the constructor should be able to normalize that property to a radius. What do we want to do with our circle? Well, we could grow or shrink it, and we want to learn what its properties are.

The latter operation is the key: how do we access the properties? It seems to me that asking for a property is one type of operation, and therefore one method. What kind of property we want to learn of is a parameter. No need for get/set pairs, here -- just a single learn method

package Circle; use strict; use warnings; use constant ATR_RADIUS => 0; use constant Pi => 3.14159; sub new { my $self = bless [], shift; $self->redefine(@_); return $self; } sub redefine { my $self = shift; my ($prop, $value) = @_; my $radius = 0; if ($prop eq 'radius') { $radius = $value; } elsif ($prop eq 'area') { $radius = sqrt( $value / Pi ); } elsif ($prop eq 'circumference' or $prop eq 'circum') { $radius = $value / ( 2 * Pi ); } elsif ($prop eq 'diameter') { $radius = $value / 2; } else { die "Property '$prop' cannot be defined"; } $self->[ATR_RADIUS] = $radius; } sub learn { my $self = shift; my $prop = shift; my $radius = $self->[ATR_RADIUS]; my $value = 0; if ($prop eq 'radius') { $value = $radius; } elsif ($prop eq 'area') { $value = Pi * ($radius ** 2); } elsif ($prop eq 'circumference' or $prop eq 'circum') { $value = 2 * Pi * $radius; } elsif ($prop eq 'diameter') { $value = $radius * 2; } else { die "'$prop' is not a property of a Circle"; } return $value; } sub grow { my $self = shift; my ($prop, $value) = @_; my $old_value = $self->learn($prop); $value += $old_value; $self->redefine($prop => $value); } sub shrink { my $self = shift; $self->grow(shift, 0-shift); # shrink is neg. growth } 1;
<-radiant.matrix->
A collection of thoughts and links from the minds of geeks
The Code that can be seen is not the true Code
"In any sufficiently large group of people, most are idiots" - Kaa's Law

Replies are listed 'Best First'.
Re^2: The Accessor Heresy
by itub (Priest) on Nov 28, 2005 at 23:17 UTC
    Using a cascaded if/elsif/else instead of individual methods looks terribly awkward to me. I think that's part of what OO and methods (or even subroutines in general) are supposed to help us avoid!

      Yes, the implementation is poor, but it is meant to be a simple demonstration. I tend to choose dispatch-table type patterns for such things, and if the normalization/etc. were more complex I might even have "private" subroutines to deal with the attributes.

      My post is more targetted toward interface than internal implementation; still, your point is a good one.

      <-radiant.matrix->
      A collection of thoughts and links from the minds of geeks
      The Code that can be seen is not the true Code
      "In any sufficiently large group of people, most are idiots" - Kaa's Law

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://512420]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (3)
As of 2024-04-19 19:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found