9 ms·
It took me an embarrassing amount of time to fully grok what object oriented programming really means. It's one thing to have someone tell you what an object is
by rolenthedeep 4y ago
It took me an embarrassing amount of time to fully grok what object oriented programming really means. It's one thing to have someone tell you what an object is, but it's another thing entirely to build a fully object oriented system.
I remember what made it click: I was designing an animation system, which had a bunch of different interdependent moving parts. Once I started treating each part like an object and letting it manage its own state it all just clicked. I started with this massively complex functional-like system that managed four or five different motions, but once it was broken into objects most of the code just fell off and it became a nice clean system.
I was super proud of it at the time, but it's pretty bad by my current standards.
- zabzonk 4y agoI've always found OO programming completely natural. n fact, it's the only kind of programming i've ever really done - create a structure with data members, and then create functions to work on that structure. you can (and should) do this in low-level languages such as C and assembler. Of course, if you want to go the whole polymorphic route, i'd suggest using something like c++, but the key ideas are really structures, and functions that operate on those structures.
- opportune 4y agoAs someone who started programming in BASIC, OO is a really good way to think about stuff (it introduces the abstraction of “conjoined data” that is typed and has functions) but it was not natural. It just feels natural now that I’ve spent so long in school and at work dealing with OO languages. I imagine if you had started with BASIC you’d feel the same
- sureglymop 4y agoI've always had a hard time because I was thinking.. why would I carry the performance hit of instantiating objects for a bunch of stuff?
- rolenthedeep 4y agoWhy accept the performance hit of copying structs when you could use a reference type? It's a tradeoff. OOP makes sense for certain types of problems, and functional programming solves other problems. It's very much a case of selecting the right tool for the job. I recently transitioned from C# game programming to C++ embedded system firmware. Objects don't make much sense for what I'm doing now, and I'm coming to see the elegance of functional programming. There is no one answer, just a box of tools. What makes a good programmer is understanding each of your tools well enough to decide which one will solve your problem in the way you want.
- zabzonk 4y agoyou have to instantiate variables anyway. grouping those variables in objects simply makes your code more understandable - there is really no extra cost.
- intelVISA 4y agoCould be wrong but, at least in C++, there's realistically no overhead to creating a trivial object that you wouldn't have by manually instantiating the variables anyway. (Ignoring virtual stuff, lengthy constructors -- code run is code run but a raw object I think is by itself relatively harmless.)
- zabzonk 4y agoyou are right - in c++ (and in most other languages that support oo) there is no overhead on instantiating a structure, or variables, that you would not have to pay anyhow.
- intelVISA 4y agoI really struggle outside OO paradigms as well. Having classes is such a useful framework to organize how data is stored, operated on, and moved around. The hardest bit is knowing when to stop, aiming for the RAII sweetspot in C++ is the goal not AbstractBeanFactoryFactoryBuilder().
- xigoi 4y agoIf the functions are not built into the objects, that's not object-oriented programming.
- opportune 4y agoMy first job was doing mostly Lego-pieces greenfield development. I learned a lot, but also didn’t learn as much as in my second job where I started having to work with a much more complicated, slightly “legacy” system with a big codebase. At small code sizes, OO does not really have any apparent advantages to doing everything imperatively or in a hacky way. In fact I’d argue it tends to overly complicate and obfuscate things. But there is a point at which you really start wanting OO instead because you can no longer reason about the binary as a whole, and need to start thinking in terms of interfaces with separation of concerns. Even if you did understand the whole state, there are too many people working on it to keep up with changes to the whole state in a way that lets you reason about the thing as a whole. At my first job (and in college) code never reached such levels of complexity so OO always seemed like some dumb fad to make things more complicated than necessary. I still that is often the case, but now I absolutely see the benefits when they present themselves.
- AndyNemmity 4y agoThis one is the same for me. I'm not even sure I still totally get it. It feels like something used an awful lot in ways that don't really add any value. But again, it must just be my lack of understanding. Maybe one of these days it'll click in.
- rolenthedeep 4y agoIn my animation system, I had a laser beam projecting from a fixed point to a movable point in space. There are also sprites which travel up and down the beam. Moving the beam endpoint required an animation to bring the width to 0, change the endpoint, then ramp the beam width back up. The sprites each have their own animation in different conditions, and moving them along the beam is another animation. The real key for me was the sprites. I built a class which takes in the start and end points of the beam and an update method. Once you start the sprite up, you just have to poke it every frame with the time delta and it manages all of its own animations. Likewise, the laser itself was an object that managed its own animations and the sprites related to it. This resulted in a bunch of objects with just a little code in them. But because the concerns are separated, it results in less code overall than it would take to manage everything all at once. Is this the best, or even a good way to do this? Probably not, but it was a very beautiful solution in the moment
- runald 4y agoNah, none of what you described (encapsulation and separation of concerns) is specific to OOP, you could do that with FP or imperatively with plain structs and functions. It's more like you are starting finally understand how to program in the large. I'm not completely against OOP, but written code that strictly adheres to this paradigm tends to be more convoluted than necessary.
- analog31 4y agoI read the earliest articles on OO and SmallTalk in Byte Magazine, which IIRC would have been the early 80s. OOP was totally and utterly bewildering to me, a BASIC and Pascal programmer. It "clicked" much later, in two stages, using languages that were "kind of like" OOP, even if not rigorously so: LabVIEW, HyperCard, Visual Basic. I think VB had a decent strategy for introducing OO to the rest of us. Out of the box, it was "object based," meaning that you could use classes that had been created by someone else. For a bit more money you could buy the version that let you do full OO, but I never did that. But by being a user of objects, it gave you an idea of what you'd want if you could create them for yourself. Nowadays of course people range from being bullish to bearish on OO, and I've had the experience of doing it badly and making a mess of things, when a procedural or functional model would probably be better. Kind of a lesser issue is that I finally grasped how to work with a modern OS after laying my hands on the first couple volumes of the Win32 programmer's manuals, which I think were vastly less forbidding than Inside Macintosh.
- layer8 4y ago> the first couple volumes of the Win32 programmer's manuals What books exactly are you referring to here?
- analog31 4y agoThat's a long time ago. ;-) As I recall, there was a set of 2 or more books, published in the early 90s. And I never had my copy, but several of the software devs had them on their shelf, and I'd borrow them as needed. Typically, my use was to write a binding for Visual Basic. For instance I hacked into the audio hardware, and wrote a bespoke interface to the serial ports. It was strictly API stuff, not how the actual OS works inside.
- deleted 4y ago[deleted]
- gurchik 4y agoWhen I was younger I had a lot of trouble with OOP. It probably didn’t help that my two strongest languages at the time (PHP and Python) allow you to use them fully iteratively if you want. For some reason I never found an explanation that focused on state. A lot of the examples I saw I remember thinking it made a lot more sense to just rewrite the functions so they aren’t part of a class. I still frequently see code examples online that are written using classes that don’t need to be. I imagine this is the reverse problem: people from languages like Java thinking everything has to be in a class.
- kevinmchugh 4y agoYes, looking back I was shocked to realize how little my oop education and work had talked about state
- czx4f4bd 4y agoI 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.
- 4y ago
- moloch-hai 4y agoYou don't really understand OOP until you recognize it as one style among many that you may use in different parts of each program. Some parts are naturally OO-y, others DD-y, others declarative, often an unholy mix in each place. The problem dictates elements of the solution. Shoehorning a solution into a particular style makes a bad solution. Never forget who is in charge. Deferring to a style dodges responsibility for your choices.
- ShredKazoo 4y agoDD?
- dopidopHN 4y agoMy guess would be domain driven design. I remember that being all the rage 10ish years ago? I think it works, but I don’t see it much anymore
- bitwize 4y agoDomain-driven or data-driven (not sure which).
- moloch-hai 4y agoData-driven. What weather prediction, finite-element analysis, and current AI do.
- hnick 4y agoPerl's approach to OOP has flaws but it being generally "data structures you already know but with some magic and functions attached" helped me understand it on a more fundamental level. It greatly supports the mix-and-match approach you mention here.
- rileyphone 4y agoI had a similar shift in perspective recently, that went from viewing objects from the outside as things to be manipulated, to viewing them from within as independent entities with boundaries. What made it click for me was watching Alan Kay talks and reading “Object Thinking” by David West. Now, I think the idea is due for some sort of renaissance. Though the culture of programming has turned against it in favor of FP, OOP continues to underlie the most important languages, organizations, and products in a way that speaks to its ultimate potential: to build evolvable, growable, maintainable software systems in service of human flourishing.
- voidhorse 4y agoI doubt you're the only one, and I actually feel that a lot of people that find themselves having to program in an OOP language don't really understand OOP fully or what its motivations are. I personally don't think it's possible to really grok OOP without first understanding the motivations for its origins and how it compares to doing everything in a purely imperative fashion. The best way to actually understand its purpose (and flaws) is to implement an OOP system in an imperative language (e.g. implement a basic OOP class system in C, etc.) It's common for a lot of online resources (I don't know about university) to provide introductions to programming using OOP, which I think is a terrible mistake. It fills beginners' heads with all sorts of incorrect, fanciful ideas about how computers work and what happens when a program is executed. It's also difficult to know how to use OOP concepts and structures correctly without knowing why they're convenient. I strongly believe you need a good understanding of the technical motivations for such constructs before you can actually use them with good effect--otherwise you're simply relying on imitating patterns or taking certain things as foundational when in fact they are not. I think functional languages and strictly imperative languages are far more appropriate for a first programming language.
- rolenthedeep 4y agoVery much agreed. My main problem with school was being told "how" and not "why". If I were to teach programming, I'd start with straight up assembly. Give people a taste of what the cpu is actually doing under all your abstractions. Probably a few weeks, enough for hello world, fibonacci numbers, and an intro to branching. Then introduce C, get used to pointers and basic high-level language concepts. Really hammer in the idea of thinking like the CPU and being mindful of the resources you're using. From there, guide them towards building a real application in imperative C or C++. After that the overarching theme is rewriting the application in an object oriented language, with attention to why and when you should and shouldn't use these new tools. IMO, understanding the fundamentals of how a cpu works is absolutely essential for writing good code at any level of abstraction, and it seems a lot of new programmers are missing that.
- ipnon 4y agoAn object is a function closed over its variable default arguments.