[Tutor] designing POOP
alan.gauld at btinternet.com
Mon Feb 11 21:37:32 CET 2008
"bhaaluu" <bhaaluu at gmail.com> wrote
> States, getters-setters, direct access.......
> I'm still in toilet-training here/ 8^D
> Can you provide some simple examples that
> illustrate exactly what and why there is any
> contention at all?
State is just a bit of jargon to describe the combined
values of an objects attributes. Here is an example:
def __init__(self, initial=0, delta=1):
self.value = initial
self.delta = delta
self.value += delta
a = Counter()
b = Counter(1)
c = Counter(0,5)
print a.state, b.state, c.state
So all 3 objects have different combinations of values
so they have different states.
The state determines the value returned by the objects
x = a.inc() # x-> 1
y = b.inc() # y -> 2
z = c.inc() # z -> 5
This is fine and dandy but what if we want to find out the
current value of a.value without calling inc?
Thats where hetter/setter/direct access comes into the
In Java and some other languages the idiomatic thing
to do is provide methods prefixed with get/set for each attribute
def __init__(self, initial=0, delta=1):...
def getDelta(self): return self.delta
def getValue(self): return self.value
def setValue(self, val): self.value = val
def setDelta(self, val): self.delta = val
Now this is a lot of typing! It also isn't necessary in Python
because Python allows you to access the attributes
diectly - direct access. Like so:
a.delta = 42
This gives rise to a debate between the OOP purists who say
that you should only access the internals of an object via a
method(get/set) and the pragmatists who say its OK to use
direct access. And old school OOPers like me say it would
be better if you didn't need to use either since you should
define the object in terms of higher level abstractions/methods.
Now, with my pragmatic hat on I see no point whatsoever in
writing reams of get/set code just for the salke of it, so if you
must bypass the abstract methods use direct access. But
what if you want all of the attributes - to print state say?
Thats where the question of direct access versus a state()
method comes in. My preference is to provide a single
method that returns the values that you need (and in many
cases thats less than all of the attributes!) rather than allowing,
or even encouraging, direct access.
The danger with direct access is that we use it not only for
reading but also for directly modifying the attributes - and
that is a bad OOP habit! (Remember: Objects do it to themselves!)
For example we want to decrement a counter instead of
we could do it directly:
c.value = c.value -5
But it would be better to do it in an OOP way.
So the final issue (and Kent will no doubt have more to add
from his perspective!) is if we do want to modify the Counter
how do we do it (assuming we don't own the original class
or too many other projects already use it to risk breaking
them)? Well, the pure OOP way is by sub classing.
Thus if we want a counter with a dec() method as well as an
inc(), we can create one:
self.value -= self.delta
Now if we make c an instance of UpDownCounter we can do:
c = UpDownCounter(0,5)
And this has the advantage that there is no impact on the
other objects derived from the initial Counter class. Note that
as well as adding methods you can also modify, or change
entirely, the existing methods, that's called "overriding a method"
and is probably left for later!
I hope that makes sense, its about the simplest example
I could come up with.
Author of the Learn to Program web site
More information about the Tutor