-2

So, recently I have been doing a lot of programming in Python. I have noticed that my programs can be somewhat hard to read. I usually have one main class which does everything, sort of like this:

class main:
    def __init__(self, *args, **kwargs):
        # Make baseline variables here
        self.foo = "bar"
        self.hello = 12345
        # Get starting input.
        self.inputted = self.get_input()

    def get_input(self):
        inputted = input("Hello, world!")
        return inputted

    def do_something(self):
        # Do data processing, make stuff, call other functions within the class.
        pass

main()

I have been doing this for purposes of making variable access easy. Considering how it messes with code readability, should I be using another approach? If so, what?

  • Is there any particular reason why this should be a class? – user253751 Jan 6 at 14:28
  • See the last paragraph. – SE is too politically correct Jan 6 at 23:13
  • It's a class "to make variable access easy"? These are basically global variables and the usual rule of "try not to use global variables" applies. – user253751 Jan 7 at 11:03
  • @user253751 What I mean is that, while yes: you should not use global variables, sometimes you need to pass variables between functions, which can be a pain. By using the class approach, I can avoid the otherwise necessary globals. – SE is too politically correct Jan 7 at 14:59
5

Refactoring

Lots of people have written tomes and tomes on the subject. Martin Fowler has some good advice. Highly recommend looking through his work, also take a look at Kevlin Henney.

Sprout and Split

The problem is that you are writing a god class. Which is not a bad first approximation when you don't know how to solve a problem. Its just not a great long-term solution.

Sprouting is a technique where you look for small snippets of coherent code in the class, and extract them out into a reasonably named function/method (also on the same class).

The benefit of doing this is that it is easy to de-duplicate small snippets of code distributed throughout the class, and it is also easier to make larger functions smaller by removing a couple of lines at a time from them.

The downside is that your class goes from having say ten functions, to having hundreds.

This is where splitting comes in. You will likely notice as you sprout methods that the methods start to form categories. These functions are about input, those functions are about calculation X, these ones are about error reporting, etc... You will find that most of the variables on self are only used by one or two of these categories of functions and often the data path will be linear. Created here, read there.

The trick is to create a new class with one category of functions. Move any shared state along with it, and perhaps add a constructor to set that state up. Now rewire the original class to call an instance of the new class when it desires that category of service.

The pro here is that the program tells you what its structure actually is. And it does this in a very mechanical way.

The downside is that the structure revealed to you is not likely to be good. After all you write a god class because you don't have a good structure in mind, and instead have opted for finding something that works, rather than something that works well. You will likely have to take what you have learnt and rewrite large portions of the architecture several times before it will even start to resemble a decent solution.

  • Thank you, this is very helpful. ++1. – SE is too politically correct Jan 6 at 0:28
  • I've struggled for a long time with how to communicate techniques for refactoring code from large classes into many small classes. The terms "sprouting" and "splitting" do a great job of this. Great answer! +1 – Greg Burghardt Jan 8 at 22:56
  • @GregBurghardt I wish I had come up with them, but I can't lay claim. I read them in a book. I think it was called: Working Effectively with Legacy Code. – Kain0_0 Jan 8 at 23:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.