18 Mar 2012
The real problem with OO is taking it too far
I just finished watching this talk by Jack Diederich (Python core developer) – somewhat flamebait-ishly named “Stop Writing Classes”. In his talk, Jack shows, through various examples, how introducing a class just for the sake of it actually makes the code harder to read and maintain.
While reflecting on the talk, I realized that the actual problem here is that people take OO too far. I don’t know how OO is taught elsewhere in the world, but from my own experience, a large part of this abuse can be attributed to the way OO is preached in various CS courses. A lot of emphasis is placed on grilling into young heads the virtues of OO and it’s place in the big enterprise world, without actually explaining why OO works when developing large applications. And, do courses on OO actually highlight when it does not work?
In interviews, when asked to solve a tricky problem, I find it disturbing that people immediately start off with skeletons of classes. It has become some kind of protocol that one should be modeling everything in classes and objects to come off as a competent software developer. Jack shows a succinct solution to Conway’s game of life problem. A solution that highlights the programmer’s knowledge and elegant use of Python’s
yield, but which will probably be rejected as “poor procedural code” in a lot of places.
In many ways, OO has become a safety belt. By having a few classes, atleast no one can fire you for writing procedural code right? If poorly written procedural code is death by repetition, poorly written OO code is death by multiple levels of insane abstractions.
One technique that has worked for me when solving a problem from scratch is to first actually solve it by using functions that perform highly specific operations. As the solution evolves, I start identifying fragments of code that can either be pulled into a separate class for better abstraction or moved from one class to another. This way, my code moves towards object orientation based on actual need, rather than because of a hypothetical high level “modeling” of the problem. This way, I also don’t end up with a class like this:
class Foo(object): pass
Simply because I (hopefully) would have felt stupid refactoring something, anything to that.