5 ms·
Here are some thoughts about OOP I had recently, maybe someone here had similar thoughts: It seems to me that the biggest cause of maintenance problems in obje
by taffer 6y ago
Here are some thoughts about OOP I had recently, maybe someone here had similar thoughts:
It seems to me that the biggest cause of maintenance problems in object-oriented programming is that it tries to manage global mutable states by partitioning and encapsulating all state into objects.
However, the only way to prevent two unrelated objects from manipulating the same part of the state is to create a strict dependency hierarchy or arborescence[0] between all objects in the system.
This combination of data and code in a strict hierarchy means that all data access patterns are baked into this dependency tree, which makes later, unforeseen changes to the software extremely difficult without taking shortcuts in the dependency tree and thereby destroying the encapsulation, which would destroy the whole point of OOP in the first place.
[0] https://en.wikipedia.org/wiki/Arborescence_(graph_theory) https://en.wikipedia.org/wiki/Arborescence_(graph_theory)
- dpc_pw 6y agoThat's a very interesting observation, that is very much aligned with my own views, but I'll need some time to absorb the details here. I'm myself on the quest to fully understand what is really wrong with OOP and then try to share it with more people. It's actually very hard because it's a complex topic, ridden with subtleties, and even the exact definition of "what is OOP-code" is elusive. I've just recently made a reddit post that you (and other's who find your post interesting) might also enjoy: https://www.reddit.com/r/rust/comments/ju5oqp/how_to_avoid_repetition_without_inheritance/gch4gbp/?context=6 https://www.reddit.com/r/rust/comments/ju5oqp/how_to_avoid_r... I wish there was some "OOP-deniers" community, where we could discuss things like that with an open mindset. Usually discussing OOP degenerates quickly and it's impossible to even establish some shared understanding.
- atty 6y agoI am a little confused about your point - are you saying that OOP is a strictly worse, or has some inherent irredeemable flaw that is not present in other programming styles? Because that’s a statement that would need a lot of supporting evidence, considering the success of OOP over the last 30 years or so. I think a more strongly defensible position is that OOP is not a magic bullet that works for all types of problems, and identifying when and where it is a natural fit is not always obvious.
- dpc_pw 6y agoFrom my experience, the modern Java-style OOP that I've worked with (some of which I produced myself) through all these years leads to terrible code, and all the data-oriented code I've seen and produced seems much, much better in comparison. Other programming styles are often orthogonal. One can have mostly functional OOP and mostly functional data-oriented software, or imperative OOP vs imperative data-oriented software and so on. I'm mostly focused on OOP vs data-orientation. OOP means a fixation on modeling everything as "a graph of encapsulated objects with associated bits of logic calling each other" while data-orientation means: "pure logic decoupled from data, and a data stored and passed in mostly non-abstract, concrete ways to support required computation". The success of OOP is dubious: mostly judged by it's popularity, which is mostly driven by it being a default methodology tough to people in school. When you look at the actual industry, most of the fundamental, long-lasting software is actually written in some form of data-orientation. From kernels, system tools, things like redis, other databases, etc. Though one could tell that it's because fundamental software is usually system software, and not business-logic software and that's true. I don't have evidence, and it's all just my experience, reasoning and intuition, and I'm intellectually open for debate here, but IMO fundamentally splitting data into small encapsulated chunk that form a graph of native references to each other is just a terrible way to organize any form of computation. I don't want to repeat myself, so please see my reddit post that I linked before for more details.
- alquemist 6y agoThe seductive power of OOP has little to do with the technical merits. As you mention data oriented programming leads to better programs. Even when using OOP technology, programs usually tend to become data oriented (hello protos), and 'objects' become glorified pure functions. The big OOP idea is the subject-verb-object interface, confusingly named object-method-arguments. The SVO structure matches the cognitive linguistic bias of the human brain, thus feels obviously right to most humans. Even if better programming alternatives exist. The endless litany of new Verber(args0).verb(args1) is here to stay.
- dpc_pw 6y ago
- submain 6y agoOne of my problems with OOP is that it is often hard to compose. One could argue that most of the OOP design patterns were made as an attempt to solve that. In FP, composition is done elegantly (at the cost of increased complexity in other areas, such as state management). Scott Wlaschin has a great talk about that: https://www.youtube.com/watch?v=4jusLF_Xz7Q https://www.youtube.com/watch?v=4jusLF_Xz7Q
- meheleventyone 6y agoProbably 90% of the problem is setting yourself up in opposition to OOP at all rather than preaching the gospel of what you consider to be good. Even if you don't have a weak argument it does make your conviction look questionable if the preamble always has to be about how dumb the other thing is. A lot of the criticism of OOP could also use more steelmaning rather than picking on claims that often feel like the opposite.
- dpc_pw 6y agoTrue. Though I guess I don't have a chance to reverse the river made out of a constant stream of developers produced by universities and bootcamps, who think "Cat extends Animal and makes_sound with "meow" and Dog extends Animal and makes_sound with "woof". I'll try to keep it in mind if I'm ever to make a book or something like this about this subject.
- meheleventyone 6y agoYeah exactly what I mean, if your target is the understanding of OOP that comes out of intro courses at University then it's easy to knock down. To the point even OOP advocates complain about it. Steelmanning for example would be taking successful, performant OOP projects and tackling the way they use it. V8, LLVM or UE4 for example off the top of my head. Steelmanning is realizing that you can write data oriented code in OOP projects. Steelmanning is realizing that you can write an ECS-style database with OOP. It's further realizing that the ECS pattern as described is not inherently data-oriented and requires extension to actually meet that criteria (e.g. archetypes). And to be clear I'm not accusing you of ignoring these things but the discussion around this topic in general. Basically as a game programmer of over 16 years of professional experience I feel a lot of this stuff is dubiously presented. And I don't even like OOP particularly!!
- dpc_pw 6y ago> Steelmanning is realizing that you can write data oriented code in OOP projects. It's going to be arguing about names and definition, but I can't accept that it's OOP, when that put qualifiers on all "4 tenets of OOP", etc. Something like: - Abstraction(*) - Encapsulation(*) - Inheritance(*) - Polymorphism(*) (*) where useful, when necessary, but ... generally avoid. If someone could tell me which book is "The BEST OOP out there, then I would be happy to read it and then argue with it" :D
- jackthemuss 6y agoWhat a load of intellectual horse-shit. Speak english DOC
- dang 6y agoThis sort of attack will get you banned on HN. Could you please read https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html and stick to the rules? Note that they include this one: "Be kind."
- dgb23 6y ago> his combination of data and code in a strict hierarchy means that all data access patterns are baked into this dependency tree I believe OOP is really good at modelling state and really bad at modelling data. With state (and side-effects modeled by state machines) you want a well-defined interface, messages, local retention and so on. This way you get the benefit of reasoning about state in a constrained manner both as the caller and the callee. For example it makes sense to model Mario as a state-machine that receives messages from game-pad (pressed buttons) and collision events. Note that this is a conceptual, high level kind of modelling and not a concrete, structural one. But data is about something. There is data about Mario at any given point in time: his physical dimensions, his velocity, consumed power ups and so on. This is where OOP makes no sense at all. Reading and transforming data should be universal/uniform rather than guarded by idiosyncratic getters, setters and so on. This is why SQL, JSON, XML, HTML, Unix filters, AWK, Functional Programming etc. are so powerful. These technologies provide/enable a uniform/universal way of reading data and composing transformations. (As a side-note: I consider state that never leaks as an implementation detail, usually for performance)
- airstrike 6y ago> his physical dimensions, his velocity, consumed power ups and so on. Aren't his physical dimensions just attributes of the Mario instance (or class definition)? Similarly, his velocity, consumed power ups and so on can all be attributes of the stage he's in. His extra lives can be an attribute of this current game session.
- dgb23 6y agoMario‘s attributes are a composite of different measurements that are partly needed in different contexts of the simulation. They are just data. And like any data we should be able to query it without knowing Mario‘s special access pattern.
- pjmlp 6y agoUsually that just shows the lack of understanding of how to use OOP, and what should be proper classes, what should be interfaces or categories, depending on the language.
- tarcon 6y agoI think adhering to the Solid principles prevents those problems. Single-responsibility should prevent two things working on the same data, dependencies should only point to abstractions and if you feel that a class hierarchy is hard to change favor composition over inheritance.
- taffer 6y agoI honestly don't see how SOLID avoids the problem I mentioned, but let me clarify this: When I say dependency, I mean it in a general sense, i.e. if a stateful object A uses a stateful object B, e.g. by composition, then A depends on B. So the behaviour of A does not only depend on the state of A, but also on the state of B. It does not matter if A or B are defined as abstractions, because in the end all object instances are concrete. These dependencies will always form a directed graph in some way. You are correct that the principle of single responsibility prevents two objects working on the same data. However, as I wrote earlier, this means that the dependency graph must be a perfect hierarchy, also known as an arborescence or out-tree. A perfect hierarchy does not allow shortcuts, so if A depends on B and B depends on C and A wants to know something about C, we always have to go through B, regardless of whether we are actually interested in B or not. This is what I mean when I say that data access is baked into the dependency graph, making it difficult to adapt OO programs to new requirements.
- discreteevent 6y agoBut the alternative is that more data needs to be exposed and then if you change that data all the functions that operate on it need to be changed. This is a well known problem. With OO you can change some of the data/state (and the resulting behaviour of the system) with just a local change. But if you want to change the functions then you are out of luck.
- tabtab 6y agoI believe languages should allow the programmer to define the relationship between one code block and another. This includes scope and state relationship. Think more powerful lambdas with better interface syntax and options. OOP languages typically hard-wire such relationships into a limited set of relationship conventions. This results in OOP graphs that don't fit the domain or need well. Sure, one can do such in Lisp, but many find Lisp hard to read. With C-style languages, the "ugly" syntax gives helpful visual cues. Stuff within (...) is usually a parameter list, stuff within {...} is usually sequential code, and "[...]" indicates indexing of some kind, for example. I find such helps my mind digest code faster. Lisp aficionados will often claim "one gets used to" the uniformity. But that's like arguing we don't need color because one can "get used to" seeing in black and white. To a degree, yes, but the color adds another dimension of info. Easily recognizable group/block types is another color.