| The author’s OO example is hard to understand, but they’re wrong about why. It’s not bad because it’s OO, but that it’s very badly done OO: the class couples two different concerns (network API client and database). That’s why it makes more sense as a bag of functions. The general version of the point doesn’t work very well, and many of the other OO use-cases the author discusses actually work much better than alternatives. For example, on abstract base classes: if you replace this with a bag of functions I think you end up reinventing virtual dispatch—that is, each function’s top level is a bunch of `if isinstance(...)` branches. This is much harder to read, and harder to add new implementations to, than abstract methods. It’s also no easier to understand. (There is a subset of this advice that I think does improve your code’s understandability, which is “only ever override abstract methods,” but that is very different from “don’t use OO.”) For impure classes, the author suggests e.g. using `responses` (an HTTP-level mocking library) instead of encapsulating these behind an interface. This is a fine pattern for simple stuff, but it is not more understandable than a fake interface. The hand-written fake HTTP responses you end up having to write are a lot less readable than a mock implementation of a purpose-built Python interface. (Source: I once mocked a lot of XML-RPC APIs with `responses` before I knew better; it was not understandable.) |
This argument seems to come up for every criticism of OO. The criticism is invalid because true OO would never do that. It seems like a No True Scotsman. Notably, when you whittle away all of the things that aren’t true OOP, you seem to be left with something that looks functional or data-oriented (something like idiomatic Go or Rust). There isn’t much remaining that might characterize it as a distinct paradigm.