[Tutor] designing POOP

Alan Gauld 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?

I'll try.

State is just a bit of jargon to describe the combined 
values of an objects attributes. Here is an example:

class Counter(object):
    def __init__(self, initial=0, delta=1):
         self.value = initial
         self.delta = delta
    def inc(self)
         self.value += delta
         return self.value
    def state(self):
         return (self.value,self.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 
inc method

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

class Counter(object):
    def __init__(self, initial=0, delta=1):...
    def inc(self)...
    def state(self):...
    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
print a.value

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:

class UpDownCounter(Counter):
      def dec(self):
          self.value -= self.delta
          return self.value

Now if we make c an instance of UpDownCounter we can do:

c = UpDownCounter(0,5)
print c.state()
print c.state()

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.

Alan Gauld
Author of the Learn to Program web site

More information about the Tutor mailing list