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

In reply to Re: The Accessor Heresy by radiantmatrix
in thread The Accessor Heresy by Roy Johnson

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.