9 ms·
First time I have heard of object-oriented obfuscation. I get it, but in general I don't get the OO hate. It's all about the problem domain imo. I can't imagi
by beachy 11mo ago
First time I have heard of object-oriented obfuscation.
I get it, but in general I don't get the OO hate.
It's all about the problem domain imo. I can't imagine building something like a graphics framework without some subtyping.
Unfortunately, people often use crap examples for OO. The worst is probably employee, where employee and contractor are subtypes of worker, or some other chicanery like that.
Of course in the real world a person can be both employee and contractor at the same time, can flit between those roles and many others, can temporarily park a role (e.g sabbatical) and many other permutations, all while maintaining history and even allowing for corrections of said history.
It would be hard to find any domain less suited to OO that HR records. I think these terrible examples are a primary reason for some people believing that OO is useless or worse than useless.
- pavo-etc 11mo agoI am currently being radicalised against OOP because of one specific senior in my team that uses it relentlessly, no matter the problem domain. I recognise there are problems where OOP is a good abstraction, but there are so many places where it isn't. I suspect many OOP haters have experienced what I'm currently experiencing, stateful objects for handing calculations that should be stateless, a confusing bag of methods that are sometimes hidden behind getters so you can't even easily tell where the computation is happening, etc
- Romario77 11mo agoYou could write crappy code in any language. I don't think it's specific for Java. Overall I think java is pretty good, especially for big code bases.
- stefs 11mo agoBut there's a real difference how easy it is to write crappy code in a language. In regards to java that'd be, for example, nullability, or mutability. Kotlin, in comparison, makes those explicit and eliminates some pain points. You'd have to go out of your way and make your code actively worse for it to be on the same level as the same java code. And then there's a reason they're teaching the "functional core, imperative shell" pattern.
- fiddlerwoaroof 11mo agoOn the other hand, Java's tooling for correctly refactoring at scale is pretty impressive: using IntelliJ, it's pretty tractable to unwind quite a few messes using automatic tools in a way that's hard to match in many languages that are often considered better.
- throwaway2037 11mo agoI agree with your point, and I want to second C# and JetBrains Rider here. Whatever refactoring you can with Java in JetBrains IntelliJ, you can do the same with C#/Rider. I have worked on multiple code bases in my career that were 100sK lines of Java and/or C#. Having a great IDE experience was simply a miracle.
- stefs 11mo agoThe language Kotlin is actually developed by JetBrains
- fiddlerwoaroof 11mo agoI've found that IntelliJ's refactorings don't work as well for Kotlin as Java but, also, I've avoided Kotlin because I don't like it very much.
- taneq 11mo agoYou gotta admit, though, that a language which strongarms you into writing classes with hidden state and then extending and composing them endlessly is kinda pushing you in that direction. It’s certainly possible to write good code in Java but it does still lend itself to abuse by the kind of person that treated Design Patterns as a Bible.
- stirfish 11mo ago>kind of person that treated Design Patterns as a Bible I have a vague idea of what the Bible says, but I have my favorite parts that I sometimes get loud about. Specifically, please think really hard before making a Singleton, and then don't do it.
- taneq 11mo agoOK yeah that's a pretty good general principle. You think you only need one of these? Are you absolutely certain? You SURE? Wrong, you now need two. Or three.
- BlackFly 11mo agoA singleton is more than just, "I only need one of these," it is more of a pattern of "I need there to be only one of these," which is subtly different and much more annoying.
- com2kid 11mo agoSingletons are so useful in single threaded node land. Configuration objects, DB connection objects that have connection pooling behind them, even my LLM connection is accessed via a Singleton.
- quantified 11mo agoSeparation of data and algorithm is so useful. I can't really comment on how your senior is doing it, but in the area of numeric calculations, making numbers know anything about their calcs is a Bad Idea. Even associations with their units or other metadata should be loose. Functional programming provides such a useful intellectual toolkit even if you program in Java. Sorry to learn, hope you don't get scar tissue from it.
- Jensson 11mo agoBut that is what classes does, it lets you have data lists and dictionaries implemented as a class so that your algorithm doesn't have to understand how the data structure is implemented. In functional programming the algorithm has to be aware of the data structure, I feel that is much worse.
- HeavyStorm 11mo agoNot sure how many people are writing programs with lots of numeric calculations. Most programs in my experience are about manipulating records: retrieve something from a database, manipulate it a bit (change values), update it back. Over here OOP do a good job - you create the data structures that you need to manipulate, but create the exact interface to effect the changes in a way that respect the domain rules. I do get that this isn't every domain out there and _no size fits all_, but I don't get the OP complaints. I currently think that most of the anger about OOP is either related to bad practices (overusing) or to lack of knowledge from newcomers. OOP is a tool like any other and can be used wrong.
- quantified 11mo agoCreating good reusable abstractions is not easy. It's quite possible to create tarballs of unusuable or overwrought abstractions. That is less of a knock on OOP and more a knock on the developers.
- zelphirkalt 11mo ago> I recognise there are problems where OOP is a good abstraction, but there are so many places where it isn't. Exactly. This is the way to think about it, imo. One of those places is GUI frameworks, I think, and there I am fine doing OOP, because I don't have a better idea how to get things done, and most GUI frameworks/toolkits/whatever are designed in an OOP way anyway. Other places I just try to go functional.
- matthewkayin 11mo agoI agree. Neither OOP nor functional programming should be treated as a religion or as a paradigm that one must either be fully invested in or not. OOP is a collection of ideas about how to write code. We should use those ideas when they are useful and ignore them when they are not. But many people don't want to put in the critical thinking required to do that, so instead they hide behind the shield of "SOLIDD principles" and "best practice" to justify their bad code (not knocking on SOLIDD principles, it's just that people use it to justify making things object oriented when they shouldn't be).
- Quekid5 11mo ago> I can't imagine building something like a graphics framework without some subtyping. While React technically uses some OOP, in practice it's a pretty non-OOP way do UI. Same with e.g. ImGUI (C++), Clay (C). I suppose for the React case there's still an OOP thing called the DOM underneath, but that's pretty abstracted. In practice most of the useful parts of OOP can be done with a "bag/record of functions". (Though not all. OCaml has some interesting stuff wrt. the FP+OOP combo which hasn't been done elsewhere, but that may just be because it wasn't ultimately all that useful.)
- MobiusHorizons 11mo agoReact is most likely not what the author had in mind by a graphics framework. The browser implementation of the DOM or a desktop widget system is much more likely the idea.
- pjmlp 11mo agoWhile using a OOP language. Welcome to Node.js v24.10.0. Type ".help" for more information. > const fn = (x) => x + x undefined > typeof(fn) 'function' > Object.getOwnPropertyNames(fn) [ 'length', 'name' ] > fn.name 'fn' > fn.length 1 > Object.getPrototypeOf(fn) [Function (anonymous)] Object
- mike_hearn 11mo agoReact is a kind of strange dysfunctional OOP pretending not to be, to appeal to people like those on this thread ;) Function calls have state, in React. Think about that for a second! It totally breaks the most basic parts of programming theory taught in day one of any coding class. The resulting concepts map pretty closely: • React function -> instantiate or access a previously instantiated object. • useState -> define an object field • Code inside the function: constructor logic • Return value: effectively a getResult() style method The difference is that the underlying stateful objects implemented in OOP using inheritance (check out the blink code) is covered up with the vdom diffing. It's a very complicated and indirect way to do a bunch of method calls on stateful objects. The React model doesn't work for a lot of things. I just Googled [react editor component] and the first hit is https://primereact.org/editor/ https://primereact.org/editor/ which appears to be an ultra-thin wrapper around a library called Quill. Quill isn't a React component, it's a completely conventional OOP library. That's because modelling a rich text editor as a React component would be weird and awkward. The data structures used for the model aren't ideal for direct modification or exposure. You really need the encapsulation provided by objects with properties and methods.
- mywittyname 11mo agoFor me, it's the fact that the mess of DAOs and Factories that constituted "enterprise" Java in the 00s was a special kind of hellscape that was actively encouraged by the design of the language. Most code bases don't need dynamically loaded objects designed with interfaces that can be swapped out. In fact, that functionality is nearly never useful. But that's how most people wrote Java code. It was terrible and taught me to avoid applying for jobs that used Java. I like OOP and often use it. But mostly just as an encapsulation of functionality, and I never use interfaces or the like.
- Nursie 11mo agoThankfully those days are not with us any more. Java has moved on quite considerably in the last few years. I think people are still too ready to use massive, hulking frameworks for every little thing, of course, but the worst of the 'enterprise' stuff seems to have been banished.
- zelphirkalt 11mo agoI hope you are right. I really do. But I have a hunch, that if I accepted any Java job, I would simply have coworkers, who are still stuck with "enterprise" Java ideology, and whose word has more weight than the word of a newcomer. That's one of the fears, that stops me from seriously considering Java shops. Fear of unreasonable coworkers and then being forced to deliver shitty work, that meets their idea of how the code should be written in the most enterprise way they can come up with. Always makes me think of that AbstractProxyFactorySomething or similar, that I saw in Keycloak, for when you want to implement your own password quality criteria. When you step back a bit and think about what you actually want to have, you realize, that actually all you want is a function, that takes as input a string, and gives as output a boolean, depending on whether the password is strong enough, or fulfills all criteria. Maybe you want to output a list of unmet criteria, if you want to make it complex. But no, it's AbstractProxyFactorySomething.
- throwaway2037 11mo agoI don't understand these complaints. Here is a tiny interface that will do what you need: @FunctionalInterface public interface IPasswordChecker { bool isValid(String password); } Now you can trivially declare a lambda that implements the interface. Example: const IPasswordChecker passwordChecker = (String password) -> password.length() >= 16;
- devjab 11mo agoI think the OO hatred comes from how academia and certain enterprise organisations for our industry picked it up and taught it like a religion. Molding an entire generation og developers who wrote some really horrible code because they were taught that abstractions were, always, correct. It obviously weren't so outside those institutions, the world slowly realized that abstractions were in many ways worse for cyclomatic complexity than what came before. Maybe not in a perfect world where people don't write shitty code on a thursday afternoon after a long day of horrible meetings in a long week of having a baby cry every night. As with everything, there isn't a golden rule to follow. Sometimes OO makes sense, sometimes it doesn't. I rarely use it, or abstractions in general, but there are some things where it's just the right fit.
- taneq 11mo agoMuch like Agile, or Hungarian notation. When a general principle becomes a religion it ceases to be a good general principle.
- rcruzeiro 11mo ago> I think the OO hatred comes from how academia and certain enterprise organisations for our industry picked it up and taught it like a religion. This, this, this. So much this. Back when I was in uni, Sun had donated basically an entire lab of those computers terminals that you used to sign in to with a smart card (I forgot the name). In exchange, the uni agreed to teach all classes related to programming in Java, and to have the professors certify in Java (never mind the fact that nobody ever used that laboratory because the lab techs had no idea how to work with those terminals). As a result of this, every class from algorithms, to software architecture felt like like a Java cult indoctrination. One of the professors actually said C was dead because Java was clearly superior.
- mayoff 11mo agoProbably the Sun Ray computer. https://en.wikipedia.org/wiki/Sun_Ray https://en.wikipedia.org/wiki/Sun_Ray
- 11mo ago
- Retr0id 11mo agoAs a reverse engineer, I totally get the phrase. Even with non-obfuscated code, if you're working with a decompilation you don't get any of the accompanying code comments or documentation. The more abstractions are present, the harder it is to understand what's going on. And, the harder it is to figure out what code changes are needed to implement your desired feature. C++ vtables are especially annoying. You can see the dispatch, but it's really hard to find the corresponding implementation from static analysis alone. If I had to choose between "no variable names" and "no vtables", I'd pick the latter.
- meindnoch 11mo agoVtables can be annoying to follow through, but try reverse-engineering an Objective-C binary! Everything is dispatched dynamically, so 99% of the call graph ends in objc_msgSend(). Good luck figuring out what the message is, and the class of the object receiving it.
- astrange 11mo agoIsn't that easy? The message is a string in one of the register parameters to it. > Everything is dispatched dynamically Well, not everything, there is NS_DIRECT. The reason for that being that dynamic dispatch is expensive - you have to keep a lot of metadata about it in the heap for sometimes rarely-used messages. (It's not about CPU usage.)
- jdswain 11mo ago(Hi Andrew) It's the misuse of OO constructs that gives it a bad name, almost always that is inheritance being overused/misused. Encapsulation and modularity are important for larger code bases, and polymorphism is useful for making code simpler, smaller and more understandable. Maybe the extra long names in java also don't help too, along with the overuse/forced use of patterns? At least it's not Hungarian notation.
- beachy 11mo agoJason! Couldn't agree more.
- pjmlp 11mo agoObjective-C says hello in extra long names are concerned. > CMMetadataFormatDescriptionCreateWithMetadataFormatDescriptionAndMetadataSpecifications(allocator:sourceDescription:metadataSpecifications:formatDescriptionOut:) https://developer.apple.com/documentation/coremedia/cmmetadataformatdescriptioncreatewithmetadataformatdescriptionandmetadataspecifications(allocator:sourcedescription:metadataspecifications:formatdescriptionout https://developer.apple.com/documentation/coremedia/cmmetada...:)
- HeavyStorm 11mo agoHeck, I love the long names. I know, I also hate FooBarSpecializedFactory, but that's waaaay better than FBSpecFac. A sample: pandas loc, iloc etc. Or Haskell scanl1. Or Scheme's cdr and car. (I know - most of the latest examples are common functions that you'll learn after a while, but still, reading it at first is terrible). My first contact with a modern OO language was C# after years of C++. And I remember how I thought it awkward that the codebase looked like everything was spelled out. Until I realize that it is easier to read, and that's the main quality for a codebase.
- andai 11mo agoTried to modify one boolean in a codebase a few weeks ago and I had to go thru like 12 levels of indirection to find "the code that actually runs".
- tourist2d 11mo agoSounds like a problem with poor code rather than something unique to OOP.
- viraptor 11mo agotourist2d seems to have triggered some moderation trap, but wrote: > Sounds like a problem with poor code rather than something unique to OOP. And yeah, OO may lean a bit towards more indirection, but it definitely doesn't force you to write code like that. If you go through too many levels, that's entirely on the developer.
- haglin 11mo agoI find inheritance works best when you model things that don't exist in reality, but only as software concepts, for example, an AbstractList, Buffer or GUI component.
- HeavyStorm 11mo agoReally like this concept!
- qwertytyyuu 11mo agoThat's why we use depedency injection now~~!
- tormeh 11mo agoI've always wanted my editor's go-to functionality to take me to an abstract class instead of the place where the actual logic resides. Good times.
- mike_hearn 11mo agoAny modern IDE will let you immediately bring up the subclasses with a single hotkey. If you have an abstract class with only a single subclass and that's not because new code is going to be added soon then yes, it's a bad design decision. Fortunately, also easy to fix with good IDEs.
- tormeh 11mo agoIn my last project every class had a corresponding abstract class, and then we used DI to use the real class. Good to be rid of it.
- mike_hearn 11mo agoThat sort of knee-jerk over-application of a technique will ruin any codebase in any language, unfortunately. It tends to reflect a lack of confidence by the developers. They aren't entirely sure how to get best results so fall back on religious devotion to 'best practices' even when it's inappropriate, in the hope that they can point the finger later if there are problems.
- Brian_K_White 11mo agoIf everyone does it wrong, then that alone means it itself is wrong.
- HeavyStorm 11mo agoEveryone? Really, that's your take? Most code out there is OOP and I find it hard to believe that everything is wrong.
- Brian_K_White 11mo agoMost food out there is McDonalds.
- mikkupikku 11mo agoIndeed. "The purpose of a system is what it does."
- userbinator 11mo agoIt's all about the problem domain imo. I can't imagine building something like a graphics framework without some subtyping. The keyword being "some". Yes, there are those who can use OOP responsibly, but in my (fortunately short) experience with Enterprise Java, they are outnumbered by the cargo-cult dogma of architecture astronauts who advocate a "more is better" approach to abstraction and design patterns. That's how you end up with things like AbstractSingletonProxyFactoryBean.
- thesz 11mo ago> I can't imagine building something like a graphics framework without some subtyping. Let me introduce you to Fudgets, an I/O and GUI framework for Haskell: https://en.wikipedia.org/wiki/Fudgets https://en.wikipedia.org/wiki/Fudgets They use higher order types to implement subtyping as a library, with combinators. For example, you can take your fudget that does not (fully) implement some functionality, wrap it into another one that does (or knows how to) implement it and have a combined fudget that fully implements what you need. Much like parsing combinators.
- StopDisinfo910 11mo agoIt’s all about the data model and the architecture. I think people focus a lot on inheritance but the core idea of OO is more the grouping of values and functions. Conceptually, you think about how methods transforms the data you are manipulating and that’s a useful way to think about programs. This complexity doesn’t really disappear when you leave OO language actually. The way most complex Ocaml programs are structured with modules grouping one main type and the functions working on it is in a lot of way inspired by OO.
- HeavyStorm 11mo ago> grouping of values and functions Encapsulation. Which I think is misunderstood a lot, both by practitioners and critics.
- DeathArrow 11mo agoFrom my pov, both inheritance and encapsulation aren't great if you have to maintain code and add new one. Also, I dislike design patterns overuse, DDD done Uncle Bob style. Also we can think of where OOP drives many teams to: https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo... https://factoryfactoryfactory.net/ https://factoryfactoryfactory.net/ https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
- throwaway2037 11mo ago> https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpriseEdition This! Everytime I see this project, I laugh out loud. The description reads: > FizzBuzz Enterprise Edition is a no-nonsense implementation of FizzBuzz made by serious businessmen for serious business purposes. I mean come on, these guys are serious!
- lincpa 11mo ago[dead]
- naikrovek 11mo agoOOP is just not how computers work. Computers work on data. Every single software problem is a data problem. Learning to think about problems in a data oriented way will make you a better developer and will make many difficult problems easier to think about and to write software to solve. In addition to that, data oriented software almost inherently runs faster because it uses the cache more efficiently. The objects that fall out of data oriented development represent what is actually going on inside the application instead of how an observer would model it naively. I really like data oriented development and I wish I had examples I could show, but they are all $employer’s.
- jlarocco 11mo agoYeah, I agree with you, and actually like OOP where it's appropriate. Unfortunately there were so many bad examples from the old Java "every thing needs a dozen factories and thousands of interfaces" days that most people haven't seen the cases where it works well.
- stonogo 11mo agoYou're right, it is all about the problem domain. Unfortunately, there was a solid decade where that was not the typical advice, and OO was pushed (in industry and in education) as the last word in programming, suitable for all tasks. There's a generation out there who was taught programming as "instantiate a truck object that inherits from a car object" and another generation who was required to implement math using OOP principles instead of just doing math. Programming languages that did not have object models suddenly developed them, often incompatibly with the rest of the language. So, while I think that OO has its places, I understand why there's a lot of visceral response to it online.