OO approach to decision sequence?

Jordan Rastrick jrastrick at student.usyd.edu.au
Sat Jun 18 03:32:43 EDT 2005


I've coded some simple recursive tree data structures using OO before
(unfortunately not in Python though). It's not nessecarily an
ill-suited approach to the task, although it depends on the specific
details of what you're doing. What's the the piece of code from which
your if...elif fragment is taken actually supposed to do?

Without knowing more about your problem, I think the most obvious OO
approach would be to write a seperate (simple) class for each of
node_type_1, node_type_2, etc. Make sure each one provides the same
interface, i.e. defines the same set of methods. Then put the different
decision branches as implementations of a certain method in each class.

class Node_Type_1(object):
    def recurse(self):
         # do stuff here

class Node_Type_2(object):
    def recurse(self):
         # do other stuff here

only make sure you use more informative names than "Node_Type_1" and
"recurse" :)

Your if elif code then collapses to:

node.recurse()

where the node variables refers to an instance of any one of your
Node_Type classes.

OO isn't magic. You still in the end have to write the code that
implements the decision choices. In this example, its likely the OO
code is actually more verbose, since you have all the class and method
definitions to write as well.

But there are advantages. Adding new cases (new node_types) is simpler
and less error prone - you just write a new node_type class. The code
for the new class, unlike a new elif brach, is kept cleanly and safely
seperate from your existing, correctly working code. If you forget to
provide the new class with the recurse method, you get a runtime error.
But if you forget to add the case to your if..elif statement, you just
end up silently going with your sentinel "else" branch, which may not
be what you really want to do with that node_type. (in fact I'd usually
raise an exception on reaching the else branch in any such extended
if..elif structure, because it's almost always the result of an error
in your program logic)

Essentially, although you may end up writing more code, its also better
organised, since as you wish it avoids your 'conventional lengthy if
struture'.

Its a partciularily useful approach if you have several different
functions that need to branch on node-type in this fashion (e.g. pretty
print the tree, post-order traverse it, run a search over it, etc). For
each such function, you just provide a method on every node_type class.
Again, if you forget to provide the code for a certain node_type, the
error is very easy to detect.

If your problem is simple, the OO approach may be overkill - your
current if..elif code may be the most straightfoward solution. But if
the problem is complicated, or has the potential to grow more
complicated, the advantages of the OO approach may be a worthwhile
trade off. Fortuantely Python is a multi-paradigm language, so the
choice to use or not use OO according to what best suits the design and
the problem is left up to you, the programmer, and is not thrust upon
you by the language.

And you certainly don't want metaclasses or anything else that complex
and deep for something like this.

Chinook wrote:
> OO approach to decision sequence?
> ---------------------------------
>
> In a recent thread (Cause for using objects?), Chris Smith replied with (in
> part):
>
> >    If your table of photo data has several types of photos, and you find
> >    yourself saying
> >
> >    if is_mugshot:
> >        #something
> >    elif is_freehand:
> >        #something
> >    else:
> >        #something
> >
> >    then OOP will help organize your code.
>
> This struck a chord because I'm trying to refactor a top-down approach to an
> OO approach.  The reason I am doing such is to try and get my mind wrapped
> around OO design, not because the particular module will benefit from an OO
> approach (it's a simple top-down recursive tree utility).  In fact it's
> probably ill suited for OO and that is why I chose it.
>
> I've used an OO approach where I built up record (instance) content in a
> variable record file, but here I'm trying to come at it from the opposite
> direction as variable record mapping (deconstructing) would be to such.
>
> Anyway, a tree node can be any of seven types where:
>
>   if node_type_1:
>     # recurse
>   elif node_type_2:
>     # terminus - do something
>   elif node_type_3:
>     # terminus - do something else
>   ...
>   else:
>     # terminus - catch all, do yet something else
>   return #to parent
>
> So, where is the magic :~)  Seriously, how might OO help me organize this
> type of problem (alleviate the conventional lengthy if structure)?  I've
> looked at the cookbook, class interface techniques, factory functions and
> metaclasses till my head is swimming. Am I missing a bolt in the machinery
> somewhere, or simply trying to find magic that doesn't exist for a
> straightforward decision sequence?    
> 
> Thank you,
> Lee C




More information about the Python-list mailing list