Python OOP – Creating Class for Complex Functions

object-orientedobject-oriented-designpython

This question is somewhat language-agnostic, but not completely, since Object Oriented Programming (OOP) is different in, for example, Java, which doesn't have first-class functions, than it is in Python.

In other words, I feel less guilty for creating unnecessary classes in a language like Java, but I feel like there might be a better way in the less boilerplate-y languages like Python.

My program needs to do a relatively complex operation a number of times.
That operation requires a lot of "bookkeeping", has to create and delete some temporary files, etc.

That's why it also needs to call a lot of other "suboperations" – putting everything into one huge method isn't very nice, modular, readable, etc.

Now these are approaches that come to my mind:

1. Make a class that has one public method only and keeps the internal state needed for the suboperations in its instance variables.

It would look something like this:

class Thing:

    def __init__(self, var1, var2):
        self.var1 = var1
        self.var2 = var2
        self.var3 = []

    def the_public_method(self, param1, param2):
        self.var4 = param1
        self.var5 = param2
        self.var6 = param1 + param2 * self.var1
        self.__suboperation1()
        self.__suboperation2()
        self.__suboperation3()


    def __suboperation1(self):
        # Do something with self.var1, self.var2, self.var6
        # Do something with the result and self.var3
        # self.var7 = something
        # ...
        self.__suboperation4()
        self.__suboperation5()
        # ...

    def suboperation2(self):
        # Uses self.var1 and self.var3

#    ...
#    etc.

The problem I see with this approach is that the state of this class makes sense only internally, and it can't do anything with its instances except call their only public method.

# Make a thing object
thing = Thing(1,2)

# Call the only method you can call
thing.the_public_method(3,4)

# You don't need thing anymore

2. Make a bunch of functions without a class and pass the various internally needed variables between them (as arguments).

The problem I see with this is that I have to pass a lot of variables between functions. Also, the functions would be closely related to each other, but they wouldn't be grouped together.

3. Like 2. but make the state variables global instead of passing them.

This would be no good at all, since I have to do the operation more than once, with different input.

Is there a fourth, better, approach? If not, which one of these approaches would be better, and why? Is there something I'm missing?

Best Answer

  1. Make a class that has one public method only and keeps the internal state needed for the suboperations in its instance variables.

The problem I see with this approach is that the state of this class makes sense only internally, and can't do anything with its instances except call their only public method.

Option 1 is a good example of encapsulation used correctly. You want the internal state to be hidden from outside code.

If that means your class only has one public method, then so be it. It'll be that much easier to maintain.

In OOP if you have a class that does exactly 1 thing, has a small public surface, and keeps all its internal state hidden, then you are (as Charlie Sheen would say) WINNING.

  1. Make a bunch of functions without a class and pass the various internally needed variables between them (as arguments).

The problem I see with this is that I have to pass a lot of variables between functions. Also, the functions would be closely related to each other, but wouldn't be grouped together.

Option 2 suffers from low cohesion. This will make maintenance more difficult.

  1. Like 2. but make the state variables global instead of passing them.

Option 3, like option 2, suffers from low cohesion, but much more severely!

History has shown that the convenience of global variables is outweighed by the brutal maintenance cost it brings. That's why you hear old farts like me ranting about encapsulation all the time.


The winning option is #1.

Related Topic