36 ms·
The Case Against OOP Is Wildly Overstated
- Kapura 6y agoIn summary, "Object Oriented Programming is good when you don't orient your program around objects."
- api 6y agoThat sounds snarky. Not sure if that was intended or not, but regardless I read your comment as: "OOP is good when you use the object oriented structure as a tool to organize your code and data to solve a problem, but not when you try to wrap your solution or your conception of the problem itself around OOP." It's 2020, and after 50+ years of programming language research I think it's safe to say that there is no "one language to rule them all" or "one programming paradigm to rule them all." Different approaches seem to excel in different areas. OOP seems to excel when the problem involves modeling systems with discrete parts and/or where there is a lot of state to manage. In other words I'd consider OOP for a "state-rich" problem domain. I am not saying this can only be done with OOP, just that it's a viable choice. There are multiple approaches to most problems. I'd also say that bad code tends to develop different forms of badness under different paradigms. Bad OOP code is massively over-engineered, verbose, and slow. Bad procedural code is spaghetti. Bad functional code is impenetrable "write-only code" that can only be understood by its author (maybe). Bad code in multi-paradigm languages tends to have all these forms of badness.
- grugagag 6y ago> I think it's safe to say that there is no "one language to rule them all" or "one programming paradigm to rule them all. Absolutely! But when OOP was initially sold to the masses it was marketed to be that one solution to rule them all, OOP was the buzzword of the day and it stayed like that for some time to come. It is only fair that the king was dethroned to make room for equally good/competing paradigms. I don't think OOP is bad but I've seen codebases where it become needlessly more complicated and complex than it should have been. The author is absolutely right in claiming that OOP is not bad if certain things are avoided when: objects are exactly not paralleling the real world, avoiding inheritance when not coding a framework/library, not creating objects unnecessarily, not overusing design patterns, etc. But since it was heavily marketed those things could not be easily escaped from and the OOP gurus kept on adding to the list. OOP is not bad but it deserve its bashing for the hype it took the world over with.
- api 6y agoI agree about OOP being marketed that way. I remember that time. Rejecting it utterly and making it an "anti-buzzword" is equally irrational. It's a tool. Use it when appropriate.
- grugagag 6y ago> It's a tool. Use it when appropriate. I agree it is a tool but since its definition (or multiple definitions because it appears there are many conflicted OOP philosophies out there) is not very clear and it leads to a lot of needlessly confused ways of using it. If it weren't so hyped in the first place maybe it would have evolved in a more harmonious way and it wouldn't be the subject to bashing now. I personally can use it for my projects, but I am in no way inclined to save it from bashing, it did bit me multiple times when my intuition was telling me otherwise. I guess what goes around comes around.
- Kapura 6y agoI program video games; I would consider running a real-time simulation as a "state-rich" problem domain. And the constraints of running real-time simulations mean that some implementations are not acceptable. Things are not generally allowed to be slow if they can be done in a way that is fast. Because of this, many game engines are built in a way that allows high throughput for processing the state of hundreds, perhaps thousands of entities in the world. Our guiding paradigm could be described as an entity-component system; another word used to describe it has been "data-oriented design." Here's a talk about it by the guy who was our engine director at the time[0]. It is not object oriented, and it seeks to unshackle itself from many of the issues with OOP as a guiding principal. [0] https://www.youtube.com/watch?v=rX0ItVEVjHc https://www.youtube.com/watch?v=rX0ItVEVjHc
- garethrowlands 6y agoAbsolutely. And the kinds of data structures you get in an entity-component system are probably easier and more natural to use in a language such as Haskell than a typical OOP object-graph-of-mutating-objects would be. Not that anyone's programming their ECS in Haskell.
- dnautics 6y ago> In other words I'd consider OOP for a "state-rich" problem domain Why is a paradigm like FP necessarily bad for this? Not all FPs are pure like Haskell, and some exist specifically for the purpose of managing state in sane ways (for example which tolerate concurrency without introducing bugs).
- AnimalMuppet 6y agoWhich FP languages do you think would be good for managing state? I've read here on HN the idea that FP is appropriate when you can think of your program like a pipe (data comes in, data goes out). To me, significant amounts of state would be antithetical to that. Is that view mistaken?
- api 6y agoThat's a good way to put it. I've thought of it as "FP is good if you can think of your program as a single possibly recursive data transform, even if it's a very elaborate one." AFAIK it is theoretically possible to model any program that way, but it's only convenient for some problems.
- dnautics 6y agoThat's really not true for most working fp-languages. For example Julia has support for fully mutable datastructures, which, you might expect for a language designed for high performance scientific computation first. In my experience (20 years of OO programming and 5 of fp)... Almost all programs are better modeled as data transformations (recursive or otherwise). One time I did come across a data structure where this did not work, but I was not convinced that the layout of the data structure itself was wisely designed (it was tied to a legacy Django ORM layout).
- dnautics 6y agoJulia, erlang. Beyond some point you're using a DB for state anyways.
- jeffffff 6y agoi would make a distinction that data and state are two different things and argue that a lot of the mess people create with OOP is due to confusing the two. data is what exists externally to your program while state is strictly internal to your program. inputs and outputs of your program are data and not state by definition. applying OOP principles to data is an unmitigated disaster and is the source of most of the problems associated with bad OOP design. data should be modelled as plain structs and arrays. data should be trivially convertable to and from json. there should be no object/relational impedance mismatch because objects are not data. data should not be bundled with code. there should be no hidden information in data. there should be no inheritance in data (use composition instead). on the other hand, many of these principles are quite useful for encapsulating state in order to provide higher level abstractions. it makes sense to hide the internal implementation details of containers, synchronization constructs, database client libraries, and other abstractions, and to allow for multiple implementations of those abstractions which can be swapped out for different purposes. introducing a new abstraction should not be taken lightly and the vast majority of programs should not be introducing their own abstractions. if the abstraction isn't something you would put in a library and make use of in several other programs, it probably shouldn't exist. in this sense, i think it is fair to say that the article author's stance is that "OOP isn't bad but you probably shouldn't be using it", and that this is a perfectly reasonable statement to make. a lot of die-hard OOP fans would argue that this is not "real OOP" but ironically their dogmatism and inability to deal with ambiguity has done more to fuel the anti-OOP movement than anything else.
- StanLindsey 6y agoI concur, at most state and data should be related is by viewing incoming data as your initial state. Data is immutable.
- lgessler 6y agoThis doesn't speak to what I consider some of the most dangerous parts of OOP, which include the assumptions that tightly binding data and code is helpful, and that statefulness is fine to freely sprinkle throughout your program.
- mimixco 6y agoAgreed. The biggest problem with OOPS lies in its original premise: that code and data should be the same thing! This is grevious error, IMHO, that leads to nothing but problems: endless boilerplate code, lots of "interfaces" that essentially do nothing (that couldn't be done directly with said data), and debugging nightmares. I much prefer to work with systems where code and data are separate and never the twain shall meet.
- michaelcampbell 6y agoOOPs original premise is homoiconicity? Really?
- throwaway894345 6y agoI'm not sure "code is data" necessarily means "homoiconicity", but it could mean "first-class functions" (or at least that's what I think of when I hear the phrase; maybe I'm wrong); however, I'm not familiar with anyone who argues that these are fundamental OOP features (perhaps Smalltalk had first class functions, but for a very long time the most popular flavors of OOP did not).
- _old_dude_ 6y agoyes, Homoiconicity is about having the same syntax for both structure and data. First class functions means there is no conversion, again at syntax level, between a function and a value. Mainstream languages all have a way to see code as data, it's function pointer in C, delegate and lambda in C# and first class functions in Python or JavaScript.
- platz 6y agoObject-Oriented Programming is Bad (2016) https://news.ycombinator.com/item?id=19407599 https://news.ycombinator.com/item?id=19407599 (2019)
- grugagag 6y agoJust to mention, Brian Will also has a video called OO programming is good* [0]. I don't think we should take these literally, he presents what he things are some bad traits and good traits of OOP. [0] https://www.youtube.com/watch?v=0iyB0_qPvWk https://www.youtube.com/watch?v=0iyB0_qPvWk
- qmmmur 6y agoThere is no 'case' to be made against any paradigm. Different hats for different jobs.
- grugagag 6y agoYes but hyped paradigms eventually meet their own downfall
- yobi-ponti 6y agoIt has become popular to hate OOP so now people find every opportunity to discredit it. But yeah, every tool has a purpose. Don't like it in your workplace? Make a fact based case against it and do something about it.
- skrtskrt 6y agoThe author is right about ORMs. They are ridiculously over engineered solutions. (My experience is largely with Django and SQLAlchemy ORMs) As soon as you want to do something that's not already perfectly built in, everything becomes a mess of impenetrable hacks. Autogenerated Django migrations are unstable and often need to be edited to to be correct or make any damn sense. It also encourages to people to blur or just straight up stomp on the line between ORM objects - tightly coupled to your database - and business-logic objects (entities, usecases, whatever). It's the Django recommended approach, called "fat models" and it leads to ridiculous levels of coupling and impenetrable ball-of-mud code. Just write SQL and marshal it into business objects. I'm actually quite fond of doing this with the SQLAlchemy Table & Query APIs, they do most of the marshaling for you. In Go I just write the raw SQL. More generally regarding OOP: I have never seen any good come from more than one layer of inheritance.
- dnautics 6y agoAlways prescribing raw sql is dangerous: You typically want something managing your sql queries if there's user input because scrubbing out SQL injections is hard and it's not something you should be 'rolling your own'
- skrtskrt 6y agoYes, I'm really talking about using libraries that let you pass parameters into a statement, and have some level of protection against injection.
- dnautics 6y agoI was just reacting to this, which is confusing given your response. > In Go I just write the raw SQL. But in general I agree with you about ORMs (I do not use them). I'm just pointing out that when the easiest/most popular library to reach for to protect yourself against injection is an ORM, it's understandable to use it.
- winstonewert 6y agoI presume that when somebody says raw sql they mean are using parameters and not just building strings.
- lmm 6y agoArticle doesn't even make an argument. If you're not modelling things with objects, and you're not using inheritance, in what sense are you doing OOP at all? If you want to treat OOP as a tool to use when it's appropriate to the problem, good - but as you gain experience you'll find that that actually just means "never".
- flohofwoe 6y agoIMHO if a programming philosophy leaves so much room for interpretation and misunderstanding, rants and counter-rants, needs evangelizing to the "dumb masses" what it "actually" means, and all of that hasn't been settled after more than half a century, then it has turned from a philosophy into a religion (or rather, a cult). Just let it rest and move on. It's just a waste of time for everyone involved.
- bussierem 6y agoI think it's telling that I'm not able to tell whether you're talking about OOP or FP in this comment.
- xtian 6y agoIs there controversy about what FP “actually means”?
- bussierem 6y agoin as much as there is controversy about what OOP means, yes -- OOP has an established definition, same as FP. The argument about "what it means" comes from the arguments between OOP and other philosophies. People often will purposefully (or accidentally) misrepresent "what it means" to strengthen their own point (or through misunderstanding of the topic). The same happens with FP compared to other philosophies. [EDIT]: To clarify I am not advocating for one or the other. I made another post in this thread talking about this a bit. GP's comment is able to be applied to basically any technology, language, or philosophy. OOP and FP are just the two "heavyweights" in this.
- liability 6y agoThe only real contention seems to be whether "functional programming language" should describe languages that merely facilitate functional programming (e.g. lisp), or only to those that enforce it (Haskell.) Otherwise, whether or not a procedure is a function is about as clear cut as you can get. It either is or it isn't, it's not subjective.
- noelwelsh 6y agoI find the premise of this kind of article is flawed. Not because some of what the article says is incorrect, but because there is no such thing as OOP. OOPs as practised in Java, say, is very different from that in Rust (which the article mentions as having a "slimmer set of object-oriented features"). As a result trying to make generic statements about OOP doesn't really give much value IMO. You need to discuss specific well-defined programming practices to make progress. I also don't think trying to define OOP is fruitful. One can resort to textualism, going back to Alan Kay's definition for example, but this is as bad in programming (how does this definition relate to current practice?) as it is in law.
- dnautics 6y agoRuby implements the Kay concepts under the hood, and erlang is arguably a rather faithful implementation of Kay objects (though the code one writes doesn't semantically reflect that and it was developed independently for a completely different set of reasons - fault tolerance)
- winstonewert 6y agoIt seems to me that the definition of OOP is so unclear as to make the term useless. It seems to me that lots of really bad ideas were spread under the guise of OOP. But now OOP advocates are shifting the definition so that OOP either excludes are doesn't explicitly advocate those bad ideas. I have to wonder: what exactly does OOP still advocate?
- tempodox 6y agoIMO, OOP just puts too many footguns at your disposal, the most dangerous one being mutability (how normal is it that our methods mutate instance variables?). The larger a system grows the more mutability will make it even harder to understand and control. It may be tolerable in small-scale embedded software, but outside of that we should make use of the better alternatives that modern hardware affords us.
- PaulHoule 6y agoI knew a professor who worked on Density Functional Theory which can be used to derive many of the properties of materials from first principles. (e.g. "Does Iron Conduct Electricity?") This involved running FORTRAN programs on what was then considered a large supercomputer (256 nodes.) Asked what he thought about any programming technique that cost a factor of 2 in performance and he told me it was a non-starter when he ran jobs that took a month. Back when Hadoop was popular, the "cutting edge" of the thing was the system that deserialized and serialized data and some of the major ways to improve performance are: eliminating copies, eliminating memory allocations, etc. I told Rich Hickey the same thing I was told, that even though the performance difference isn't much in the grand scheme of things, people who have high performance needs are going to dismiss whatever he brings to the table if it costs them a factor of two. Interestingly, Hickey responded the same way the professor did: just as the professor dismissed the value of the 2x slower but more maintainable system, Hickey just seemed to dismiss the value of "2x faster". I see this a lot where people just don't communicate, even when they pretend they are.
- eternalban 6y agoHPC obviously prefers higher performing approaches, but how is this anecdote relevant to general programming community? The position that x2 "isn't much in the grand scheme of things" is a reasonable position. Note the "grand scheme" qualifier. Also the implicit here is "we trade performance for ---". The professor was making a sensible statement about tradeoffs when considering 'general programming approaches'. Your last line also reads like a potshot at Rich Hickey. I think the actual failure of OOP is that it did -not- result in the desired outcome of addressing the "software crisis" [1] and the significant imbalance between the scale of required (new) software and available human resources to write these systems. A subset of programmers can use OOP to build very effective systems; the rest shoot themselves in the foot. That is the failure of OOP. But I am curious if any other software methodology prevents underskilled developers from shooting their own feet. AFAIK the answer is a definitive 'No'. [1]: https://en.wikipedia.org/wiki/Software_crisis https://en.wikipedia.org/wiki/Software_crisis
- clktmr 6y ago> The solution to the fragile base class problem and other inheritance hangovers is surprisingly simple — don’t use it If OOP provides the footgun to shoot yourself, OOP is at fault. Overall the article reads as "OOP has no problems if is used correctly". Of course that's true. I have seen well designed OOP programs, but the majority was not. The author should ask the question, why OOP is applied the wrong way so often.
- Rickasaurus 6y agoThe term we like to use is "the pit of success". It shouldn't be hard to do it the right way.
- infogulch 6y agoYou are a ball. Do you want to naturally roll towards the pit of success, or struggle to balance yourself atop the tower of abstractions?
- beaker52 6y ago"The pit of success" is a great guiding principle when it comes to the design of codebases. Forget about "design patterns" and just focus on _how do I allow developers to focus on creating things that are adding value, rather than faffing around with extraneous things_. I can't tell you how many times I've seen a project go full onion-pattern with a web service that basically just recieves HTTP requests and makes a few itself and returns some data. Instead of a HTTP request handler that fetches data, perhaps does some mutation and returns it, there's a whole "service layer", a domain model, data fetching abstraction. To change something you have to navigate the winding dependency graph and fight off all the deamons. That's not the pit of success, they're the catacombs of failure. We should design codebases so that future developers fall into the pit of success, even if it means we haven't been able to show off our knowledge of software architecture etc. The best pattern you can ever apply, is the one that makes change easiest. If you make change hard, the code becomes artificially stale -- I call it 'calcified'. Coupling makes code hard to change. Thinking about problems through objects, in my experience, encourages people to make 'one model to rule them all', for example in a retail app, you might have a "Product" which ends up having product information, media assets, pricing, promotions, retail and stock keeping information etc which in a peice of software undergoing 'rapid development', multiplies the likelihood of coupling. Which is where Domain Driven Design steps in and tries to preach. Thinking about your problem in terms of data, or events can often help you find the right concepts to create your abstractions around. Another good heuristic is to think about caching, can you cache pricing for the same length of time you can cache product information, for example? Bit of a ramble, but explains why I tend to shy away from objects, except for where I have a bonafide business problem that needs to be modelled -- with this, the models are only used to make the code make sense to developers and help arrive at the result they produce, rather than the models being the result themselves.
- bussierem 6y agoThe problem I've always had with these back-and-forths between various programming philosophies is that the very nature of the argument exposes the reason the arguments don't work. The most common (but not only) way each side argues its point is to take some contrived example and show how philosophy X does it well, and how philosophy Y does it terribly. These examples are often ranted about by the "Y" proponents because "it's a bad problem choice designed to make Y look bad". Yes. It is. Because X and Y were not designed to solve the same problems. If you pick an example Y is good at, most of the time X will be bad at it. So if you're doing something like that, use Y. But if you're doing something X is good at, then pick X Why would you intentionally shoot yourself in the foot to use a framework, language, philosophy, etc. that was never intended to be used for that thing when there's something that was? Stop arguing about who's better at what. X and Y are good at different things. That's why they're _different philosophies/languages/technologies_.
- acdha 6y agoThe other related observation I make is that our field suffers from dogmatic thinking. A methodology is a tool, not a holy calling which cannot be altered: if it's working for your team, it's good; if not, adjust to something which works better. The problems come in when someone reads some over-stated screed about design patterns, pure functional programming, etc. and then decides that they have to throw every other tool in the toolbox out, and follow The Right Way™ in every possible way even when they're spending most of their time on problems of their own creation rather than their job. The various philosophies being debated will change over time but that mindset is remarkably stable.
- PaulDavisThe1st 6y agoSo let's say I've decided to sit down and write a digital audio workstation. I've got to pick at least one programming language and at least one general programming style. Let's say I pick C++ and (somewhat by implication) a generally OOP style. Someone comes along and says "oh, you could do this much better with Haskell and functional programming". How can you argue that the comparison involves an "X and Y" that are not designed to solve the same problem? Advocates for languages and programming styles are generally doing so on the basis that there is a broad class of software development problems/projects that will benefit from the use of their preferred "X and Y". Sure, there are some DSLs that are clearly not intended to be compared with (say) C++. And there are some overall programming styles that clearly suite certain kinds of software much more than others (e.g. the absence of an event loop somewhat changes everything, as does high level distributed parallelism). But OOP isn't an example of such a thing.
- gcpwnd 6y agoAs usual. People have criticism. Counter critics say get smarter. The problem is that we are dealing with largely unproven concepts. We have no facts, not even meaningful empiric insights. It is a battle of religions but it should be an academic challenge.
- dreamcompiler 6y agoPSA: If you want people to read your tech posts, don't write them on Medium. Medium requires logging in to view their content now, so like Pinterest, Quora, etc they are dead to me. And I know I'm not alone.
- gizmo385 6y agoGiven that the post is ranked relatively highly on Hacker News at the moment, it would appear that there are people who are still reading their tech post even though it is on Medium :)
- Noumenon72 6y agoI paid for Medium because I was reading so much good tech content there.
- freedomben 6y agoMight I suggest, when posting Medium premium stories to Hacker News it would be best to use the "Share Friend Link" link so people can avoid the pay wall (it doesn't affect author earnings). That seems to be what it is for: promotion outside of Medium itself. (This only works for the author so doesn't help others, but I wanted to mention it to raise awareness)
- identity0 6y agoThe author flatly says "do not use inheritance." Without inheritance and polymorphism, what is left in OOP? If you look at the author's 4 pillars, the only thing left is encapsulation (and "Oversimplified Hot Takes") It seems like the author himself has proven why OOP is bad. You can have encapsulation without OOP. People were doing it in C 40 years ago. And people are doing it in Go right now. No one would call Go an OO language, yet it has what the author admits is OOP's only good feature.
- AnimalMuppet 6y agoYes, you could do encapsulation in C. You'd have a struct. But the problem is, any function in the whole program could modify the data in the struct, possibly placing it in an invalid state. When the struct wound up in an invalid state, you had to look at the entire program to find out who did it. (C++ style) OOP encapsulation is different. Only member functions can modify the "struct" (object) data (unless you did something crazy like make your data members public). If the data is in an invalid state one of the member functions did it. Nobody else had the ability to do so. Your debugging got easier, because there's a much smaller set of places where the problem could be. Now, true, you could do that in C, with the structure declared only in one C file (and no header file), and all functions declared file static except the "public interface". But C++ make that the normal way to work, not something that you had to go out of your way to do. Inheritance: If you have a problem where it adds value, use it. It's a tool, not a religious dogma (either for or against). You could argue that most people, when they think they have a problem where inheritance adds value, are mistaken. You could even be right. But never use it? It's always the wrong choice? Get outta here. I'll use it when it helps - when the shape of the problem calls for it.
- identity0 6y agoI never said encapsulation was easy or obvious in C, just that it's nothing new or inherently OOP-based. I also never said that you should never use inheritance, I was just quoting the author, who, in his "defence" of OOP admits that OOP's only unique feature should not be used at all.
- 6y ago
- spanhandler 6y agoI think React's decision, when faced with a desire to track state alongside code, to partially reimplement objects inside of functions rather than just saying "know what, this new feature requires class syntax, deal with it" (and in fact excluding class-style syntax from the new features) is the perfect sign of where the functions-vs-OO pendulum is.
- francobatta 6y agoI recently wrote an article bashing OOP, seems like I have to rethink it now :P https://collectednotes.com/francobatta/a-case-against-java-or-bad-oop https://collectednotes.com/francobatta/a-case-against-java-o...
- jdmoreira 6y agoI wish I could read this but it’s hosted in Medium and no, I won’t create an account. Seriously why does anyone even publishes there? In fact I'm already biased against the author just because of his choice. If he can’t even bother not using Medium can I really trust he spent the time to think through what he wrote?
- dsun179 6y agoI think we should publish these articles on github as readme. Then people can even add stuff and fix typos.
- jdonaldson 6y agoI believe OOP was successful largely because of Conway's law. OOP itself is a hierarchical (inheritance) type system that mirrors hierarchical social systems in business. It's very "top down" in its orientation, and also allows teams to tightly control the information they are dealing with. Also, I didn't even read TFA. However, I think it's only fair since it's a medium post that requires login.
- goatlover 6y agoAlso because of UIs.
- drbojingle 6y agoSo you fix OOP by taking away the things that make OOP, OOP? That just sounds like procedural programming with extra steps. Also, as an aside, I wouldn't call DRY a 'rock solid foundation' of programming. People do some weird contortions to make code DRY that end up causing my harm then good. Separations of Concerns is far more important. DRY is fine when applied within the scope of a feature, but not cross features. Otherwise you end up playing wack-a-mole when you fix a bug in one place only to make a new one somewhere else.
- GloriousKoji 6y agoI knew a programmer who was all in on DRY and it was the heart of many stupid debates. Not only did result in a crazy inheritance and dependency tree, there were tons of many useless functions. Like having "logger.log(obj.read_stream())" in a few places would be "WET" the API got cluttered clutter with crap like obj.read_and_log_stream()
- drummer 6y agoOOP has served me well. It is a powerful concept. Problem is that people can misuse and abuse things.
- wvenable 6y agoIt's the most successful programming paradigm in history. I feel like being anti-OOP is like being anti-vax. It's so successful and ubiquitous that it's success becomes invisible and so people only focus on the failures or misuse. Complaining about OOP requires an entire object-oriented software stack to post your argument.
- kryth 6y agoThat doesn't make any sense. Being an anti-vaxxer is simply stupid, proven by real numbers and repeated experiments. Meanwhile, there are a lot of fair criticisms to OOP. Of course, a lot of them arise due to the fact that the skill floor for software development is quite low nowadays, but then again if we were all that smart, we'd just write C and C++ at the speed of light for everything. P.S: Rewriting hackernews in a functional stack is trivial
- wvenable 6y agoThere are plenty of potential side-effects for vaccines as well. The last time I had one, I had a relatively unpleasant reaction. So I'm not saying that there aren't fair criticisms of object-oriented programming. But "the case against OOP" is not proven by real numbers and repeated experiments. It's the most successful programming paradigm in history. The evidence for the success of OOP is more overwhelming than for any vaccine. Yet we're stilling debating boogeyman like mercury in vaccines and inheritance in OOP. Re-writing hackernews in a functional stack might be trivial. But what about the web browser, the GUI environment, the OS kernel? OOP based software stacks are everywhere. And there is no need to re-write anything because it all works fine.
- Wilem82 6y ago
- adrianmsmith 6y agoPeople love to hate on inheritance and suggest that there are no cases where its use is warranted. But inheritance absolutely is used, and successfully, in many frameworks. For example GUI frameworks [1] [2] or server-side web frameworks [3]. People have been writing code in frameworks like this for ages and as far as I can see they worked well. Including key use cases such as being able to use the provided components "out of the box" and also being able to customize them, i.e. "like this component, but with these differences". [1] https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html https://docs.oracle.com/javase/8/javafx/api/javafx/scene/con... [2] https://developer.apple.com/documentation/appkit/nsbutton https://developer.apple.com/documentation/appkit/nsbutton [3] https://ci.apache.org/projects/wicket/apidocs/org/apache/wicket/markup/html/form/Button.html https://ci.apache.org/projects/wicket/apidocs/org/apache/wic...
- arcticbull 6y agoJust because there's examples of successful usages doesn't necessarily mean that it's "good" or even a model for how we do things moving forward. Picking that specific example [NS|UI]Button, they're dreadful to work with. Honestly. Customizing them is difficult to impossible. It's often easier to just compose them into a different container because the extension points couldn't possibly be designed in a way that gives you all the flexibility you need. Yes, it works, and yes, there are great systems built with OOP patterns. The same can be said of C++. That doesn't mean they're good, or we should choose it as our tool moving forward.
- hombre_fatal 6y agoNot very compelling. Your point that people have been able to leverage something to build something applies to everything. Doesn't mean it's good nor that there isn't a whole rest-of-the-continuum of things that are better. Look at all the things humans built before 21st-century tooling. So what? GUI frameworks like NS/UIKit and CoreData aren't good. They're quite bad, actually. That's why we are moving on. It's just that the pendulum has swing so far away from OOP in our zeitgeist for enough time that the new audience is feeding a new wave of "X is actually good!" We can see the same with PHP-related HN submissions right now.
- dragontamer 6y agoThere's this "bastard OOP" where "ellipse isa circle" going around which completely doesn't work in practice. But there's "true OOP" that follows SOLID principles (particularly LSP) that actually makes a lot of sense. Unfortunately, this "bastard OOP" is the more popular variant, with many "bastard OOP" examples from the late 90s and early 00s running around textbooks, polluting the minds of student programmers at the time. This article does a good job poking fun at it, with "class Dog extends Animal", which is complete nonsense. Actually learning SOLID principles, as well as the historical 80s style of OOP, goes a long way towards fixing problems.
- commandlinefan 6y agoUsually when I see people rant against OOP, they're not ranting in favor of FP (or even better, in favor of something like Scala that combines OOP and FP) but rather in favor of a return to procedural/top-down programming. There are very good reasons that procedural programming was abandoned a long time ago and the need for global variables to make it work is one of the big ones.
- jchw 6y agoIn my opinion, the case against inheritance is strong, but it’s in favor of composition, which is still often object oriented.
- Jtsummers 6y ago> There are very good reasons that procedural programming was abandoned a long time ago and the need for global variables to make it work is one of the big ones. Procedural programming does not, at all, require global variables to make it work. I'm not a big fan of procedural programming at scale because it almost always seems to assume mutability (by default) and shared state when dealing with concurrency, but let's set those aside. You use structures to contain what a naive programmer (or a prototype) would use global state for. Instead of: player_t current_turn; // a global You do: struct game_state { player_t current_turn; } And pass that game_state value or reference around. The global state can easily be minimized or eliminated from most procedural programs. I've done this quite often as part of improving older programs.
- antonvs 6y agoThat's basically a hand-rolled implementation of a state monad that supports real mutability. The Haskell equivalent is the ST monad. While it's possible to do this kind of thing, it's busywork that properly designed programming languages are perfectly capable of handling well on our behalf.
- commandlinefan 6y agoI had the same thought: he's doing OOP without using the "class" keyword. Well-written C code is actually very object-oriented this way, it just doesn't take advantage of the syntactic sugar of C++.
- zaphar 6y agoI respectfully disagree that frameworks and stdlibs for languages like Java and .Net are better due to use of Inheritance. In fact I struggle to come up with a single occasion where use of Inheritance was not an Antipattern. The exception I suppose is when you have no other way to do polymorphic interfaces.
- donor20 6y agoI'm no expert, but the mental model of an interface is so simple. The inheritance model I liked in school, but practically the payoff just never seems to show up.
- wvenable 6y agoLots of things in software development have an is-a relationship. The only time inheritance is an antipattern is when it's used for code-reuse and it isn't modeling an is-a relationship. Once you get to application code there aren't a lot of is-a relationships but inside operating systems, libraries, and frameworks it does come up legitimately.
- zaphar 6y agoIs-a relationships are best handled by interfaces. If you don't have those and only have inheritance then that is the exception I mentioned above. In those cases I would argue that the base class should be composed entirely of abstract methods and the depth of the inheritance hierarchy should be no greater than 1.
- wvenable 6y agoIf you have something that is something else in almost every way except for one or twos details inheritance is far superior than interfaces. The other benefit of inheritance, that often goes unmentioned, is the ability to fix bugs in other products. I've had to inherit from some library/framework class to fix a bug in that technology -- it might be a rare situation but it's absolutely invaluable to have that option.
- twirlock 6y agoThe real problem with OOP is everyone thinks it means Java which encourages stupid management of dependencies. There's also that whole thing about people using it to make concrete things more abstract instead of the other way around.
- phendrenad2 6y agoOOP is a crazy academic-esque idea that happened to stick because it works at scale. When you have hundreds of programmers working on a codebase, it's useful to constrain people with UML diagrams and rigid hierarchy. Otherwise, cowboy coders hack up something the other 90% of coders can't understand. This is why languages like Scala and Haskell haven't taken off outside of a few small-team-focused niches, like data science.
- lou1306 6y agoIn my opinion the "killer feature" of OOP at scale, more than hierarchy, it's compartmentalization of code. Class hierarchies tend to have issues at scale, but OOP makes people agree on "where should we put this block of code" in a way that's "intuitive" and scales.
- creatonez 6y ago> OOP makes people agree on "where should we put this block of code" in a way that's "intuitive" and scales. This is the opposite conclusion of Brian Will's Object-Oriented Programming is Bad video. Since it forces you to think about everything as a real-world "object", OOP often leads to philosophical debates like Should a Message send() itself? Should a Sender send() Messages? Should a Receiver receive() Messages? Should a Connection transmit() Messages? With more and more abstract OOP constructs with more and more interaction with the rest of the program, knowing where to put the relevant code becomes more and more difficult. FizzBuzzEnterpriseEdition[1], while it is satire, is quite similar to a lot of large Java codebases that have been through the wringer of alternating cycles of OOAD and code rot. Try to find the right bit of code to edit if you wanted to add a new feature to FizzBuzzEnterpriseEdition. Not very easy. --- [1] https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- wvenable 6y ago> OOP is a crazy academic-esque idea that happened to stick because it works at scale. I suppose it's weird to be young enough that you're first exposure to OOP is it being taught in an academic environment. It must make it seem like it was dreamed up like some kind of formalism and spewed into your brain. But before OOP languages and everything that you describe, people using plain old procedural languages were already coding in an OOP style because it's obviously beneficial. Languages later came along to formalize patterns that people had used for years. For a more modern example you just have to look at the Linux kernel which includes a lot of OOP principles even though it's all just C.
- DonHopkins 6y agoPerson, Woman, Man, Camera, TV: The Class Hierarchy https://www.youtube.com/watch?v=LhZyHIZpzoM https://www.youtube.com/watch?v=LhZyHIZpzoM
- mopierotti 6y agoAfter working in the Scala, which blurs the line between FP and OOP, daily for years, I feel like the choice to use OOP or not tends to boil down to how you'd prefer to solve the Expression Problem [1] for your domain. (if you follow the paradigm of "Functional Core, Imperative Shell") If you're following this paradigm, for all your core objects they: -Will be immutable, meaning calling methods on them will not change their state. (except for potentially some transparent optimizations, eg in-memory caching) -Should not have methods that have side effects (i.e. purely functional) If this is the case, then choosing whether your classes are objects or simple data structs is only a matter of code organization. ie do you want objects to carry around their methods with them, or have those functions live separately. If you want to share method implementations among objects, you have the option of using inherited methods/types for a more OOP solution, or the typeclass pattern for a more FP solution. (Though the typeclass pattern has significant syntactical baggage in Scala) [1] https://wiki.c2.com/?ExpressionProblem https://wiki.c2.com/?ExpressionProblem
- _greim_ 6y agoThis is the No True Scotsman fallacy as applied to programming paradigms. https://yourlogicalfallacyis.com/no-true-scotsman https://yourlogicalfallacyis.com/no-true-scotsman
- wwright 6y agoIf there is anything in CS which should be renamed simply because people have completely incorrect assumptions from the name, it's OOP. Everyone has someone different they think about it, and almost none of it has anything to do with late-binding, encapsulation, or message passing.
- jmnicolas 6y agoSince I accepted I was no Einstein I embraced the KISS principle. My code became simpler, easier to understand. Of course it wouldn't get the approval of any software architect or any design pattern fanatic, but I can take any code I wrote 3 years ago, understand it on the fly and edit it with confidence. There are few bugs and they're never a nightmare to find. Now if I have to modify the code I was writing before my KISS revelation, when I was reading too much about OOP and design patterns then the headaches start. Often I'm left wondering why oh why I had to use so many levels of indirection to solve what is a simple problem.
- cglace 6y agoAmen. I think the mistake is to reach for the complicated patterns first. Rather than refactoring later when it’s obvious they are needed to simplify your code.
- deleted 6y ago[deleted]
- austinl 6y agoI like the theory behind app architecture, but I haven't seen a complex design pattern work well in practice (unless the team is small, and everyone has a solid understanding of how it works). I worked on a mobile app once that really tried to force one of the fancier design patterns — it required something like six files to handle one screen (because, of course, it's best practice to separate your view, view model, controller, etc.) However, a good part of the org didn't understand the nuances of what code should go where, and found it absurdly tedious to manage all of these files to build one minor screen. Velocity plummeted. I think a good design pattern allows you to scale as complexity increases. Let folks start simple, then provide a clear path to a consistent design pattern that handles more complexity as it's needed.
- nfw2 6y agoEinstein himself would approve this philosophy. As he once said, "Everything should be made as simple as possible, but no simpler." Still, finding the simplest-possible solution to complex problems is often challenging in itself, especially considering what is "simple" or "intuitive" can be highly subjective. Engineers are often uncomfortable thinking about these problems because the domain is shifted somewhat away from the realm of logic machines and towards psychology and UX, in which they have little to no education or experience.
- deleted 6y ago[deleted]
- mcqueenjordan 6y agoThere is a lot that is problematic with OO, especially if it is adhered to with dogma. The worst idea and the one I've experienced most issue with, is the `extends` keyword in Java, and more generally, the concept of inheritance. Inheritance is terribly overused, and tends to lead to code spaghetti and testing nightmares. Hierarchy is a mental trick we pull on ourselves to make sense of the world, but it rarely works out nicely in systems.
- wrsh07 6y agoPretty good takes here in the comments (shout out to references to "pit of success") There are two things worth mentioning, though. 1) the best pragmatic programming recommendation is "semantic compression" by Muratori [1]. Incidentally, I find it to be an effective "takedown" of the sort of dogmatic oop that anyone criticizing oop is criticizing 2) Muratori might disagree with this, but for me the whole point of a new class (type) is new invariants [2]. If you need a new invariant, you make a new type. Sticking to this principle has helped me keep classes small and focused without really thinking about other things like "single responsibility". There are a few exceptions (eg you might need a new type to work with a particularly clunky API, like some Map Reduce ones), but it's really that simple. As a bit of an aside, the worst code I have written hasn't been purely OO nor purely functional. It's been when I've mistakenly tried to add new ideas to existing code that break the paradigm. [1] https://caseymuratori.com/blog_0015 https://caseymuratori.com/blog_0015 [2] https://en.m.wikipedia.org/wiki/Class_invariant https://en.m.wikipedia.org/wiki/Class_invariant
- mrkeen 6y ago> If you need a new invariant, you make a new type. Agreed, but is that OO? From [2]: > Class invariants are established during construction and constantly maintained between calls to public methods. Code within functions may break invariants as long as the invariants are restored before a public function ends. That just sounds like a race condition with extra steps.
- wrsh07 6y agoI think you can use OO effectively to define invariants. (You could also do this with FP!) Beyond that, I'm not sure I understand your question.
- GordonS 6y agoI enjoyed reading Muratori's blog post you linked to - it's interesting to read the thought processes of a dev who writes so well. But I don't get how "semantic compression" is any different from the more commonly termed DRY (Don't Repeat Yourself)?
- peter303 6y agoOOP is perhaps not the best abstraction for distributed computing where you want maximize data flow and minimize distributed state. The slowdown of Moores Law for a single core/node means performance improvements will distribute computing among a large number of such units.
- cjvirtucio 6y agoI have difficulty maintaining a stance in the OOP vs. FP debate. Like, all I see in my day-to-day is OOP, so I know what good, production-ready OOP looks like, but I've never an equivalent for FP. Would be nice to see a before/after article, i.e. an OOP app refactored into FP, talking about why the latter is better.
- InfiniteRand 6y agoA little off-topic, but when thinking about the reasoning behind OOP, in particular how it shows up in C++ and the C++-influences in other languages, I think it is worth looking at how large-scale C projects (OpenSSL, Gnome, etc.) organize their code: long prefixes in front of function names complex structs with lots of function pointers complicated macros for code generation These directly relate to some of the core features of C++ like namespaces, virtual functions, and templates. I think this perspective makes the differences between C++ style object orientation and Smalltalk style object orientation understandable.
- Ericson2314 6y agoOOP is so nebulous that there's no reason to critique it.
- kumarvvr 6y agoIt's been forever that I have used Inheritance in OOP. Perhaps Python has spoilt me, but 99% of my thought process automatically pivots to composition when thinking in terms of OOP. And more towards how to name libraries, what functionality to put functions into and how to name my files. OOP is just a tool to organize code. People give it too much thought sometimes. I did too.
- brundolf 6y agoThe best thing I can say about OOP is that it allows for private state that only certain logic is allowed to know about. In some cases, you just really need that. But I think the biggest problem with OOP is that it encourages a spirit of "eager complication". Take getters/setters as a classic example. Occasionally that pattern can be useful, but standard practice in Java is to never ever create a simple public field. You always create a private field, with a getter and setter, under the assumption that later you'll need to put some special logic in there. We can't just create some plain functions, we need a Helper Class™. We can't just pass in a function's dependencies as arguments, we need Dependency Injection™. We can't just use a union type, we need a Visitor Pattern™. I think some of these habits were built in a world before certain simplifying language features were widely available (union types in particular are only recently entering the mainstream). Programmers were traumatized by the limitations of Java and the ensuing complexity of their projects, causing them to enter future projects already bracing for the worst. Simplicity is assumed to be impossible, so you just go ahead and barricade the windows with some up-front complexity in hopes of flattening the exponential complexity curve down the line. But the world has changed since then. There's a reason multi-paradigm languages are becoming so popular: because implementing real projects without creating out-of-control complexity requires having a wide range of tools at your disposal. In this new world, I think it's really important that some of these patterns get unlearned. I'll leave you with this Paul Graham post from 2002 about OOP Design Patterns: http://www.paulgraham.com/icad.html http://www.paulgraham.com/icad.html > When I see patterns in my programs, I consider it a sign of trouble. The shape of a program should reflect only the problem it needs to solve. Any other regularity in the code is a sign, to me at least, that I'm using abstractions that aren't powerful enough-- often that I'm generating by hand the expansions of some macro that I need to write.
- jdlshore 6y agoOvercomplication isn’t the fault of OOP—or any paradigm. It’s what happens when any programming technique gets a lot of traction. It’s easier to make things complicated than simple. And people tend to use ideas blindly, without understanding the context in which they’re meant to be used.
- jameshush 6y ago
- bob1029 6y agoOOP is basically a blank canvas. It is always up to the artist to bring structure and reason to it. There is never one perfect answer for every case. That said, there are some general policies that seem to make sense, namely the alignment of your object models with the shape of the business problem you are trying to solve. Perhaps your problem domain has the idea of a Customer, but there are really 3 flavors of customer. Many developers would automatically do base/derived here, but in some cases it makes sense to have these as entirely distinct types. Making this determination one way or another is at the very core of the art of software engineering. These decisions have higher order impacts that are impossible to anticipate or understand until you personally go through hell a few times. Proper management of state is another major concern. In context of OOP, I find it best to centralize state along independent verticals of business functionality. Models like CustomerCheckoutState, UserSignupState, etc. When you centralize all of the state you wish to mutate as part of one business activity into one object instance, it becomes really easy to manage. E.g. serialize your state to database and back every time the user takes an action. You can also leverage the scoped injection functionality available in many DI frameworks to pass a per-user-action state instance into all relevant business services and UI components. If you can keep your business fact modeling & stateful domains under control, the rest will likely fall into place.
- Animats 6y agoOne point I've made occasionally is that few languages support backpointers well. When B is a member of A, B often needs a back reference to A. Rust does that badly, because it doesn't fit well with the ownership semantics. C++ with move semantics does that badly, for much the same reason The same thing applies when A allocates and owns B. It's hard to get a clean, safe, reference back to A that cannot result in a dangling pointer, especially during deallocation. Object inheritance does that well. Finding the parent is easy and is done in a consistent way. The deletion process is done in a consistent, if not ideal, way. That's useful. If we had proper syntax and semantics for getting a reference back to the owning object, one of the use cases for inheritance would go away. Languages have "this" or "self", for accessing the current object, but lack "owner", for accessing the owning object. If a language offers single ownership, you should be able to find the owner easily. (Multiple inheritance is just a mess. Most, if not all, of the use cases for that are better done in other ways.)
- grawprog 6y agoI've never really gotten the hate towards OOP. It's always logically made sense to me. It follows along the path of abstraction and encapsulation computers had been moving steadily towards. It just takes the concept of a function, packages it together with some kind of data, keeps the internal workings separate from the rest of the program and allows one to reuse or extend those small pieces. It may not be the best way of abstracting above procedural programming, it's not suitable for everything, it's easy to use poorly, but it's there and it does have benefits and can exist peacefully along side other paradigms.
- Waterluvian 6y agoFWIW I’ve been a python and javascript dev for a long time. I’ve spent this year learning Rust and I’m kind of in love with the whole “it’s just a struct and here are some associated functions” thing. It feels so simple and clear. I also really liked C#’s “single inheritance plus interfaces”. That was also an eye opening moment.
- cutler 6y agoApart from Rich Hickey's "Simple Made Easy" I think Joe Armstrong summed-up best the inherent problems with OOP as it exists in the most popular languages: "The problem with object-oriented languages is they've got all this implicit environment they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."
- GordonS 6y agoSomething I'd really love to see is a GitHub repo containing different projects written in both an OOP style (e.g. with C# or Java) and an FP style (e.g. with F#, Scala or Python). F# and Scala also have both OOP and FP features - something else nice to see would be the same project written in both OOP and FP styles in the same language. Anyone have any links to repos or blog posts along these lines?
- cannabis_sam 6y agoIf this article is to be taken at face value, the case against OOP is understated... The author is in desperate need of an actual understanding of OOP, an understand of what OOP looks like in practice, and the most basic understanding of other programming paradigms (or at least a rudimentary understanding of what’s meant by procedural, structural and functional programming.)
- AtlasBarfed 6y agoI still think procedural and OOP code requires 10-15 IQ points (for some theoretical "good" measurement of IQ) than FP. Vocal proponents of languages will be on the more intelligent end of the spectrum to begin with, so this economic / structural "advantage" of OOP isn't as apparent, especially since such advocacies revolve around idealism and the hidden biases of it paying their bills.
- amznthrowaway5 6y agoIQ points less or more? I assume you mean OOP requires 10-15 IQ points less, but it is very hard to do OOP correctly so I don't think that's true.
- AtlasBarfed 6y agoMost OOP programmers aren't doing complex hierarchies or other modelling / design. They're doing singleton service patterns in Spring Boot.