A little bit about #objectorientedprogramming.
So I'm pretty cool on OOP these days, and the main reason is that I'm pretty hot on writing code that's easy to change in the future. The main advantage to OOP is that one couples the data to the methods that can manipulate the data. This is great, and makes intuitive sense.
The main disadvantage, I've decided, is that for just about all OOP languages I'm familiar with, this divides the world into two sorts of functions per object class:
* The methods the class knows about
* Everything else
... and I've come around to thinking that drawing that line is prognostication. Especially since basically all systems I deal with don't let you "open up" an object definition and add new methods. So you end up with `foo.something()` methods, but also `manipulate(foo)` methods living in some other library, and don't even get me started on whether methods that involve manipulating two objects should be `foo.do(bar)` or `bar.do(foo)` or both or neither. All of that is just noise. These days, I prefer to keep the set of "methods the class knows about" as close to zero as possible.
So what's replaced OOP for me? Usually, I'm nowadays working with interfaces, composition, functions, and generics. I find those work great, and the situations where I *really* want OOP are vanishingly small. If I want to find the "methods" of a data type, I just search the codebase for functions that take that data as an argument (trivial with modern IDEs and modern languages)... and hey, bonus, it finds me the additional functionality that someone else wrote in their module because they couldn't re-open an object to add behavior and they weren't in control of the module that defined the object!
@lobrien I agree in principle, but the thing I've come around to these past years is that principle rarely aligns with practice on large codebases (especially large, alien codebases). "Just look at the object's methods to know how to use it" turns into a lie far quicker than we want.
There were some good research projects I saw in the past on this topic, though I'm not sure what came of them. One out of Carnegie Mellon years ago crawled Google Code and augmented the documentation of Java classes with examples of the classes being returned from factory functions (because they realized it was far, far more common for Java objects to be synthesized out of complex factories than simply constructed for most frameworks people were using). Neat solution, but it was deeply machine-learning and I think it imploded when Google shut down Code Search.
(It's worth noting that colocation in a single file is ideal, and you can approach that ideal without OOP. OOP and good module design are orthogonal principles).
@mtomczak Agreed re colocation / clean modularity being orthogonal to OOP. As I wrote the response I had the obligatory flashback to the Smalltalk browser, but imagining it with your signature-based organization. Comprehending an API surface area is *such* a big problem you’d think someone would dare to take another run at a better UX. Not enough money in it for the risk, I suppose.
@mtomczak well put. I’ve come to roughly the same conclusions and generally avoid “classic” OOP wherever possible. I’m actually quite annoyed that JavaScript added classes as a supported concept…
@mtomczak Although I think it's fair to say that searching the codebase is slower and more error-prone than the OOP ideal of everything being colocated in a single file. Also, if your language or library is prone to hijinx like Python's arbitrary "key-word args," signature search and reasoning can be frustrating.