0
votes

With the goal of maximizing code reuse, I have created a rather complex class hierarchy for my Python code. It goes something like this:

class ElectionMethod
    class IterativeMethod
        class SNTV
        ...
    class NonIterativeMethod
        class OrderDependent
            class CambridgeSTV
            ...
        class OrderIndependent
            class WIGM
                class ERS97STV
                ...
            class Recursive
                class MeekSTV
                ...

Only the leaves of the class hierarchy are ever instantiated into objects. This does serve its purpose of maximizing code reuse, but the code itself is complicated (some classes have 20 or so methods) and given the many levels it can be time consuming to find where something is implemented.

I've tried pulling out chunks of functionality and putting that functionality in a separate object, but I haven't found a good way to do this since nearly all the functionality depends on common data. I.e., I can move some code to a different object but it needs to refer back to the big complex hierarchy to get the data it needs so it isn't really encapsulation.

Does anyone have any advice as to how to make this more manageable?

3
There's not much we can say without knowing the exact details of the project! You need to go over the design careful and work out what needs to inherit from what.Katriel
Thanks for the suggestions. I'll have to take a closer look to see if they can work for me.gaefan

3 Answers

2
votes

Multi-methods might, depending on your architecture, be another valid solution to this sort of problem. The idea is to make the methods module level functions that can act on any class instance which it would be desirable to pass to them. Here's a another link that examines them as an alternative to multiple inheritance. It call's them generic functions but the idea is similar. It also discusses python's un-documented built in implementation of the concept.

If you could move everything that doesn't have to do with setting or getting a particular instances values out of a class to module level functions and just have the class level code concerned with implementing a state-exposure/modification interface, then you might not even need multi-methods.

2
votes

If the only difficulty is finding where something is implemented, perhaps you don't need to refactor. Instead, look for extensions to your current editor, or switch to one that supports jumping-to-definitions.

For example, emacs with ropemacs installed jumps to definitions when the the cursor is placed over an object name and Ctrl-c g is pressed.

I'm sure there are similar tricks if you use vi/vim.

0
votes

This is classic problem, so there isn't universal answer ( otherwise it wasn't a problem ). But has several commonly used solutions. One of them - SOLID principles in design. So you haven't to search functionality trough the levels of your hierarchy, you can easily find or implement it in appropriate single-responsible code element. And if you need to access to some common data, you should create objects responsible for access to this data.

Design by Contract and especially Dependency Injection technique generally needs for some framework support, so make search for suitable platform.