5 ms·
I didn't fully grok OOP until I saw how composition and dynamic dispatch can be used in real code to create abstractions and flexibly swap out different impleme
by czx4f4bd 4y ago
I didn't fully grok OOP until I saw how composition and dynamic dispatch can be used in real code to create abstractions and flexibly swap out different implementations for your interfaces.
You could build a chatbot that supports Discord, Slack, and IRC dynamically at runtime, or a web app that can use multiple different database engines, or a social network with multiple types of posts that can all be rendered in a main feed, or a bunch of other things. In all of these cases you can also take advantage of this kind of dynamic dispatch to inject mock objects for testing, as well as theoretically have an easier time swapping out a layer if you want to change a dependency.
What really frustrates me is that almost none of the OOP instruction I've encountered ever showed these kinds of real, practical examples. They always over-emphasize harmful inheritance-based approaches and never really explain composition. In college we learned about OOP by building a little text-based RPG thing with different types of monsters implemented as subclasses of an abstract base class, which left me feeling like there wasn't much practical use for it outside of game development.
It wasn't until my first internship that I saw a real-world use of OOP, in the form of a giant Spring Boot monolith with tons of dependency injection. Eventually, after staring at that for a few months, OOP finally clicked for me, but I still find it annoying that nobody ever tried explaining this using practical, small-scale examples.
- beachy 4y ago> What really frustrates me is that almost none of the OOP instruction I've encountered ever showed these kinds of real, practical examples. They always over-emphasize harmful inheritance-based approaches and never really explain composition. So true. The canonical example used by OO pundits is often a "Person". A Person can be either a Contractor or an Employee (inheritance). Having spent a lifetime in HR systems, there really couldn't be a worse example. It turns out that people may become contractors or employees, and then change back again, leaving the company and then returning. Some people may even hold the role of contractor and employee contemporaneously. Any crazy shit is true for humans. Instead of using simple OO classes to model people, IRL you end up with many, many tables that capture their lifecycle. Good OO candidates/examples are usually non real worl things. Window managers and windows. Progamming concepts. That kind of thing, where the rules are simple and point in time.
- hnick 4y agoFor me, the issue was that OOP in an academic context was always toy examples. OK, Dog and Cat are Animal that can MakeNoise, Eat, and HaveFur (except sometimes not). Yeah, I get it. It's a ridiculous amount of boilerplate compared to just throwing some functions in and getting it done. The issue was that anything they taught had to be dumbed down to the point to fit in a classroom and they basically stopped there. We also never wrote code that would be looked at by more than one person. I didn't "get it" until I spent years in a real job, with systems complex enough for this to matter, and practical examples like Dependency Inversion etc as you say. There was also a complete lack of Composition and (at the time I did it) multiple-inheritance which is a bit more controversial these days. Our traditional Comp Sci course also worked on a variety of languages but nearly zero UI or web programming back then, which are both natural fits for OOP that we largely ignored.
- PaulStatezny 4y ago> I didn't fully grok OOP until I saw how composition and dynamic dispatch can be used in real code to create abstractions and flexibly swap out different implementations for your interfaces. > You could build a chatbot that supports Discord, Slack, and IRC dynamically at runtime... As a counter-point, OOP isn't necessary for dynamic dispatch. None of these dynamic features you describe are necessarily any harder in non-OOP languages — or easier in OOP languages. You can do the same kind of dynamic dispatch in Elixir, Go, etc. OOP really is a preference, not a differentiator. Source: I cut my teeth on OOP and used it for many years. Been using Elixir for the last half a decade, and have zero loss of ability to do things like this.
- Transfinity 4y agoI agree. IMO, Java-style OOP conflates 2 different concepts, polymorphism and inheritance. Polymorphism (including dynamic dispatch and duck typing) is a game changer, in that it encourages simple, stable interfaces, enables testing, encourages encapsulation, etc. It's a key technique for building big projects. Inheritance is a tool for reducing the amount of code written by a human, among many others (things like code generation and composition) I haven't seen it unlock other important conceptual domains the way polymorphism does. Unfortunately many undergraduate curriculums get overly excited about inheritance when teaching OOP. I guess animal-cat-dog is an easy example (though totally unrealistic), but the problems polymorphism solves don't often show up in classroom-sized projects.
- czx4f4bd 4y agoYes, the general applicability of these concepts is exactly why they should be emphasized when teaching OOP rather than wasting time on uselessly contrived examples of inheritance. However, I'm not really sure why your comment is framed as a counterpoint to mine. I explained what it took for me to grok OOP, but I never said OOP alone provides composition and dynamic dispatch. It seems needlessly antagonistic to make this some kind of programming paradigm pissing contest when that has nothing to do with anything I said.
- mekster 4y agoExamples totally do suck. A class Animal is inherited by Dog class that barks. That's like the total opposite of what any practical example can be and people confuse how that's even useful.