9 ms·
Moving Beyond the OOP Obsession
- sklogic 11y agoClasses are among the worst ways of implementing modularity. Compare them to, say, SML modules.
- golergka 11y agoI've encountered this code a lot in C, and every time I thought that this style of > stuff_do_something(stuff, some_parameter) _is_ OOP and identical to > stuff.do_something(some_parameter) , although in language without support for OOP (of course, you can hack OOP on top of C with preprocessors and stuff, but let's pretend we forgot about that embarrassing abominations). And every time I saw that I wished that I could type the second one instead, just because of how more natural it feels.
- mercer 11y agoI like the latter too, but where 'stuff' is a namespace rather than an object in the traditional sense.
- V-2 11y agoThe missing link is extension methods/functions, which are sort of syntax sugar for the former (letting it pretend to be the latter)
- AndrewDucker 11y agoExactly. OOP is: a) A code naming/organisational issue b) Some formalisation of structure, so that developers can specify what is/isn't allowed in their code. Both of thise have advantages and disadvantages, and the structure can be over-formalised and made too complex. But this doesn't make OOP bad. It makes bad design bad.
- jdminhbg 11y agoWell yes, when you redefine "OOP" to mean "well-organized code," then all well-organized code is object-oriented. That's not what people mean when they refer to OOP though -- they're talking about data+behavior encapsulation, inheritance, message-passing, etc.
- marcosdumay 11y agoOOP is not "well-organized code". It is a specific kind of code organization that derives a good part of its value from being universal.
- sparkie 11y agoI don't disagree with the author's sentiment about inheritance (or OOP in general), being used and taught wrongly, but I still think it's a necessary tool to have available. Without inheritance, as soon as you want to cast mixer to something else, you're either relying on binary wizardry by the compiler (reinterpret_cast. ie, undefined behaviour), or you need to break encapsulation to copy the fields over from one object to another. Of course we could use an opaque pointer to our objects instead, but if your solution is to cast anything to (void*), where could that possibly go wrong? OOP inheritance is pretty much doing that, but in a constrained, statically enforced way, which prevents programmers from making elementary mistakes or trying to make assumptions about the way hardware works. Of course, the last example of the singleton works, but it also doesn't help to explain why we might use singletons in OOP. If we assume we have both a hardware mixer and a soft mixer which both have the set volume method, we wan't polymorphism so we can treat them equally. In the author's solution, we must treat each specially at the call site, which also violates our open/closed principle - we want to add new mixers without hacking (and breaking) the existing code. Still, I pretty much agree that we should rethink the way these are taught. Perhaps every student should write his own OOP language before being let loose with it.
- l_dopa 11y agoYou're describing subtyping which, like modularity, does not require inheritance or really any other part of "OOP". I think that supports the article's point that C++, Java, etc. only support certain language features in an ad-hoc way tied to their object systems, making them, among other things, poor teaching languages.
- rlidwka 11y ago> Without inheritance, as soon as you want to cast mixer to something else, you're either relying on binary wizardry by the compiler Why would you want to cast mixer to something else? What real-life task does it solve? > If we assume we have both a hardware mixer and a soft mixer which both have the set volume method, we wan't polymorphism so we can treat them equally. Polymorphism isn't OOP feature. You can have overloaded `mixer_set(struct, int)` without any OOP wizardry involved.
- Nutmog 11y agoWhat baffles me about OOP is that massive aspects of how to use it have changed, and that change happened after it gained popularity as a good technique. How could it have become popular when people were doing it wrong? The article mentions inheritance, but there's also heavy vs light classes. When I was taught OOP, an object knew how to do all the things to itself. It could draw itself on the screen, modify itself, save itself to a file, etc. Now that's turned on its head and is bad practice. So if OOP was great with inheritance and heavy classes, how can it now be bad with inheritance and heavy classes? Were the original OOP evangelists doing it wrong and promoting something they hadn't actually tried enough to discover its problems (ie hype)? Was it just misunderstood and inheritance has always been known to be something to avoid and light (single public method) classes always been a good idea but computer science professors didn't understand it?
- coldtea 11y ago>What baffles me about OOP is that massive aspects of how to use it have changed, and that change happened after it gained popularity as a good technique. How could it have become popular when people were doing it wrong? Your arguments boils down to "how come something that had utility X at some point in time, have less than X at a later point", which frankly I don't think is surprising at all, nor logically contradictory (which seems to be the assumption). How is that surprising? It happens with most emerging programming paradigms/technologies. They first get popularity for some new benefits they bring, and then, as the dust settles, the community finds out the best ways to do something, shapes their best practices etc. Two examples: 1) JAVA. Initial lure: runs anywhere, easier to use than C/C++, fast, etc. Java, then went through the crazy J2EE, XML everywhere, etc phases, and after that they found a balance on how you should write code, including adopting more functional styles now. 2) PHP. Initial lure: dead easy to install, comes with every function webdevs needed at the time, runs on all cheap hosts, easy syntax. Community used crappy coding practices, bad idioms etc, but slowly improved their ways, found new ways to structure code, etc. >So if OOP was great with inheritance and heavy classes, how can it now be bad with inheritance and heavy classes? That was then, and this is now. Neither CPUs, nor the available programming languages, nor needs, nor our collective understanding of programming is the same. The same way "Finding Nemo" might be good when you're 10 (and given your other options at the time), but at 30 you have a lot more movie options... 1) CPUs: are now multicore, and OO is NOT the best way to get advantage of them (push towards pure, functional, etc). 2) Available programming languages: then, at least the mainstream ones where ...assembler, plain Pascal, C, etc, compared to which OO was a novel and handy way to structure programs. Now we have much more options. 3) Needs: back then --80s, 90s-- it was the golden age of Desktop GUI programming, for which OO is a quite good match. For web programming and the kind of work we do now, not so much. 4) Collective understanding of programming: back when a closure was something exotic, and functional concepts totally alien to most programmers, even OO was too foreign for some, but at least they understood it. So it was a good match for the average programmer then. Nowadays programmers come out of universities, or learn on their own with the millions of internet resources, and have a match better understanding of programming idioms, exposure to new ways to code, etc.
- stickfigure 11y agoWe actually used to write "OO" C code like this - lots of it - back in the Xt Toolkit Intrinsics days. It sucked. Writing GUI systems in C++ was a massive improvement. Sometimes syntax matters.
- DanielBMarkham 11y agoI've been saying this for years. Historically, yes, OOP has its own roots. But for all effects and purposes, C++ with headers controlling visibility is the grandfather of OOP. If you got that, then you've got OOP basics. (And, as the author points out, 90% of what you'll ever need) There's another way of "going beyond OOP" that bears some thought, and that's growing a program by incrementally adding functions, then grouping the functions into modules. This is actually the same point as the author is making, but looking at it from the other way. It occurs to me that if we started with writing code using pure functions, over time those functions would naturally accumulate into cohesive modules. A methodology that taught this could well end up being the TDD of the next generation of coders.
- woah 11y agoThis is how Node js development tends to be done.
- exprx 11y ago>Now here's what this would look like in C++ without using objects: mixer_set_volume(m, 0.8); What is m, if not an object?
- lexicality 11y agoA struct.
- exprx 11y agoA struct is an object. Even a plain integer is an object, considering the referred article was talking about C++. (Yes, you cannot inherit all kinds of objects – but you definitely can inherit any kind of struct, POD or not.)
- rfrey 11y agoWell, if everything is an object, I guess everything is an object. Usually when people are talking about OO objects they mean data+behaviour.
- jschwartzi 11y agoObject refers to a memory object, which could be data or text(functions).
- mcphage 11y ago> when people are talking about OO objects they mean data+behaviour The distinction between behavior being "a set of methods defined inside a class", and "a set of methods whose first param is a particular type of struct" is not that important.
- nlawalker 11y agoThe distinction between "a set of methods with privileged access to encapsulated internal state of a class" and "a set of functions whose first param is a particular type of struct, and operate on members of that struct that everyone can access" is pretty critical though.
- sklogic 11y agoA value, with a type. Nothing else. Stop highjacking everything into your OO religion. If you take everything of a value that originated elsewhere, there will be nothing left in the OOD.
- heartsucker 11y ago> Stop highjacking everything into your OO religion. The parent to your post seemed to have a legitimate question, and you're being snarky. You could have left out everything after the first sentence or even explained what that means in practice.
- sklogic 11y agoIt was a bad argument disguised as a "question". I rarely tolerate this sort of a discourse.
- exprx 11y agoA value with a type is an object? What else do we need? “Methods”? Why? I very strongly support the proposed Unified call syntax.
- sklogic 11y agoThe word "object" comes loaded with a shit ton of ideology. There is absolutely no need to rename the long established terms to simply please a bunch of religious zealots.
- scomment 11y agoOkay, now give me some collection like object, who can handle everything. No, don't use void*. There are some benefits if everything is an object, like generics.
- sklogic 11y agoEver seen STL? It is as anti-OOP by design as it gets.
- jakub_h 11y agoI could take that text more seriously if it at least discussed the limitations of the most powerful embodiments of OOP that we have today and not the accidental limitations of languages that for one reason or the other ended up not as good as they could have and force you to jump through hoops, as evidenced by the very mentions of classes, constructors, private methods etc., none of which are fundamental to OOP but all of which were made fundamental to certain languages.
- hcarvalhoalves 11y agoI agree, but OTH you can be a Platonist and refute every criticism with this argument. In the end the OOP you have is the OOP that has been implemented, so judging the implementations we have to work on is more down to earth.
- jakub_h 11y agoTrue. But when it comes to learning the basics of programming, you can always pick better languages. There doesn't appear to a shortage of pedagogically useful ones.
- whoisthemachine 11y agoI agree with this post, and especially the main focus of the post, which seems to be: teach the basics before bogging students down in the crazy terminology-heavy industry we live in.
- Chirael 11y agoYes absolutely. I learned OO with programming in the early 90s, around the birth of the OO religion. So it's definitely in my mental toolbox if needed... But in practice I'd say I rarely, if ever, need it. The only time it's come up in the last 5 years was during a job interview, when I mentally did an eye roll and thought "oh god OOP stuff again" Granted, I do more glue programming and scripting, vs full-fledged app development. I'm sure if I was doing Android apps I'd be using ActiveWindowAppAdapterFactoryConstructor (q.v., programming in the kingdom of nouns) but thankfully that's not something I have to do (yet).
- w8rbt 11y agoThere's a lot of non-OOP C++ outside of the classroom ;) Procedural C++ is big in systems (and that's not just plain C compiled with a C++ compiler). Templates, strings, built-in containers and smart pointers are very popular and useful.
- CyberDildonics 11y agoIf you need an interface to your data, use structs/classes. If you need genericness when the size of the data doesn't change, use templates. If you need genericness when the size of the data does change, use inheritance. If you need genericness with respect to part of an algorithm, use lambdas.
- whatnotests 11y agoThank you for succinctly putting this to words.
- CyberDildonics 11y agoNo one technique scales on its own. Assembly, macro assembly, expressions, functions, classes, inheritance, templates, closures, data flow, and even message passing if you want performance. Everyone keeps looking for the silver bullet, but ends up with answers that are simple, easy, and wrong. If there is a bullet at all I think it is accepting that software architecture is made up of all these things + tools that give lots of extra information easily + interactivity and small iteration times. I think when most people are being overwhelmed with complexity they want a silver bullet so badly they will believe that there is one against all evidence to the contrary.
- bitcointicker 11y agoAnother good article expressing a similar opinion which some might not have seen http://blog.codinghorror.com/your-code-oop-or-poo/ http://blog.codinghorror.com/your-code-oop-or-poo/
- ufo 11y ago"Object Oriented Programming" in Portuguese is "Programação Orientada a Objetos". So for me the two categories are one and the same :P
- dboreham 11y agoThe author seems to genuinely not know that this is the original motivation for C++ -- to provide syntactic sugar and additional type safety to the very techniques he describes, which were (and still are) widely used in C. It is as if I am reading a "Software The Onion". Hmm...checks date...
- scomment 11y agoOkaaaaaaay, so if we left everything what OOP gived us (properties^1, generics, lot of good patterns^2, lot of abstractions for generic things, like interface^3, events, higher level datastructures, delegates, namespaces, modules^4 etc.) then we get C? Omg, thank you Captian Obvious! Learn OOP first. What a bullshit article. 1) C++ for OO example? Seriously, why??? Grab a modern language who have properties at least. Even Delphi had it! 2) IMHO without OO patterns OOP worth nothing 3) I know, you can do interfaces in C++ with pure virtual classes, but you miss the abstraction behind that. 4) Java JAR, .NET assemblies, no matter what they called.
- aikah 11y agoNot sure I understand the point of this article, especially in the context of C++ where encapsulation with classes helps avoiding things like memory leaks, dangling pointers and co. If you feel you need to code C style, use C, with all the problem it might incur.
- CuriouslyC 11y agoPersonally, think object oriented programming gets a fair amount "right". That isn't to say there aren't problems. Specifically, classes as a mechanism of packaging data together with all the functions that act on that data is a good idea. Additionally, I think classes are more intuitive and generally tend to be syntactically clearer than their functional equivalent, namespace factories (though less semantically explicit). Fluent style chaining of method invokation is also a lot easier to read than nested function calls in most languages. The biggest issue I have with classes is the concept of constructors and destructors. These are semantically unclear and basically break multiple inheritance. Aside from that, in dynamic languages classes also encourage people to write code that checks class type, which is both brittle and potentially limiting, depending on the context.
- vannevar 11y agoYou could generalize the described approach even further and have a single global function called 'message', so that your entire app consists entirely of statements like: message(receiver, msg) Sure, it's encapsulated, but it's hardly modular. The author knew not to do this because he's undoubtedly already had a lot of experience with OOP. So writing OOP-like functions comes easy to him. I'm not sure that would be the case for a beginner, who could also go to the other extreme and have a different function for everything, even if two methods differ only in their arguments: add_one_to(number) add two_to(number) etc. The point of OOP is that it provides some guidance in navigating between the two extremes, and tools to manage modularity and redundancy (like inheritance and composition). Encapsulation isn't the sole benefit.