22 ms·
OOP Is Dead, Long Live OOP
- faragon 8y agoMore resources on DOD (Data Oriented Design): https://github.com/dbartolini/data-oriented-design https://github.com/dbartolini/data-oriented-design
- Chabs 8y agoOne thing that I'm surprised this doesn't cover, especially since it's so C++-centric, is that modern C++ OOP is much more defined by lifetime/scope management than anything else. What defines something as an object is the fact that it doesn't exist until it is constructed, and doesn't exist after it gets destructed (which is the case even for fundamental types, with the exception of char/std::byte, btw). Hot take: RAII has basically taken over everything else as far as structural design foundation goes. Type erasure and encapsulation still play a role, but it's not nearly as fundamental anymore.
- stochastic_monk 8y agoRAII is my primary use for objects in C+++, and I believe Rust is similar. Inheritance has fewer uses for me.
- Ace17 8y agoRAII is a very powerful technique. However, it has actually very little to do with object-orientation. To my knowledge, the only other langages having it are D (multi-paradigm) and Rust (explicitly non-object oriented).
- std_throwawayay 8y agoOOP is just a mental model. Deep down everything is made of bits. The church of OOP has failed but if something looks like a duck, walks like a duck and talks like a duck it probably is useful to make a duck class. We're now down to fighting for nuances. You can do most things with OOP or without OOP but each path has some upsides and downsides and most of the time it's good to use some things it provides where it makes sense and not get too religious about it. The great architect has the foresight on how the code will be used in five years and design it accordingly.
- Nursie 8y agoYup, I like to think the religious war has subsided, and we're a little more free to do things in ways which work, are concise, readable and maintainable, even in previous bastions of enterprise OOP fervour like Java.
- Waterluvian 8y agoI think this relates to what you're saying. I've never felt any frustration that OOP feels like the wrong tool when I'm using languages that give me the choice to use it or not (like Python, and JavaScript). But when I'm using Java, as one example, it often feels like I'm really locking myself into a design up front. In Python, especially. I'll find myself starting off all experiments or simple projects with functions and basic data types. As something evolves and I want some semantic clarity I'll stop using dicts and start using namedtuples. And then at some point I may replace the namedtuples with classes. From there I may discover value in having subclasses so I'll add a few (but this is exceedingly rare in my line of work).
- Chabs 8y agoBut that's the whole point of JAVA. It's an opinionated platform with a hyper-standardized workflow. Sure, that limits creativity, but in many business contexts, the last thing you want is your programmers getting "cute". There's a straight line from requirements to implementation; no meandering involved. At least that's the theory. In practice...
- Waterluvian 8y agoYes. That may very well be. And I'm not saying Java is bad because of what I described. Just that I experience the, "ugh OOP isn't helping me do what I want to do here" with Java.
- std_throwawayay 8y agoIt probably is the right tool if you have an enterprise problem that needs an enterprise solution.
- evancox100 8y agoAuthor needs to actually state what ECS is. From context I don't think he/she is referring to Amazon's Elastic Compute Service.
- gagege 8y agoIn a gamedev context, ECS stands for Entity Component System.
- flohofwoe 8y agoIt's Unity's (the game engine) new Entity-Component-System, the blog post is an answer to this presentation: http://aras-p.info/texts/files/2018Academy%20-%20ECS-DoD.pdf http://aras-p.info/texts/files/2018Academy%20-%20ECS-DoD.pdf Unity's traditional entity system is suffering from a number of "OOP-isms" which make it hard/impossible to optimize for performance. The new ECS strictly follows a Data-Oriented-Design approach, where everything is built around laying out the data in memory in a CPU-cache friendly way (and a few other things that neatly 'fall into place', like spreading work across CPU cores, a specialized 'high-performance' C# dialect, and the ability to move work from the CPU to the GPU). The big question is how the traditional Unity audience will react, since the ECS programming model is quite a bit different from the old way, and it's no longer as simple to build a game from a jenga-tower of adhoc-hacks ;)
- reificator 8y agoI'm very glad that Unity is doing this, and it's made me interested in the engine for the first time in many years. However, it's important to note that Unity is adding an ECS, not inventing the concept.
- TeMPOraL 8y agoI don't think Entity-Component-System is Unity-specific. From what I recall from other articles, Unity has its own idiosyncratic implementation, but the pattern has several slightly different interpretations.
- 8y ago
- maxxxxx 8y agoIf we just had made inheritance as something to be avoided unless absolutely needed then OOP would have probably never got such a bad reputation. All the other concepts make perfect sense.
- pjmlp 8y agoWe made it optional in many languages, the problem is how it many people teach OOP, and how it gets abused.
- 3pt14159 8y agoI've found that inheritance is very useful in one situation, and adds nothing over mixins otherwise. If a class does two broad things simultaneously then inheritance can work great. For example, a User class that inherits from a DB mapper class. I don't want to have to tell my class how to write a record to the DB. All that code can be centralized into one thing and then relied upon for its uniformity across all my models. This isn't true the way most people use inheritance though. They do things like Sword inherits from Weapon and Weapon inherits from Item. But this just asks for trouble because as requirements get more complex there are more edge cases and the complexity bubbles up into overriding the inherited methods, which makes them less reliable from different calling contexts, or flipping the OO script and pushing class-based-if-statements in the ancestor class. Then you step back and say "why did we make Sword a weapon in the first place?" and the answer was we had logic somewhere else in the code that did things like check if a user was armed. Well we don't need inheritance for that at all. We can use plain old methods and properties / duck typing.
- Chabs 8y agoFrankly, having User inherit from DBMapper is way more egregious in my eyes than Sword inheriting from Weapon. It doesn't really matter because both of these things can be better solved using composition + traits/interfaces anyways.
- maxxxxx 8y ago"adds nothing over mixins otherwise." The funny thing is that languages like C# and Java abandoned mixins but kept deep inheritance hierarchies. When I did C++ more we used multiple inheritance a lot but with only one or two layers deep. This worked extremely well and now that that I am doing more in C# I miss it a lot.
- Reedx 8y agoSome other takes: Casey Muratori (Handmade Hero) on why OOP is bad and how to get rid of that mindset - https://youtu.be/GKYCA3UsmrU?t=4m50s https://youtu.be/GKYCA3UsmrU?t=4m50s Mike Acton (Engine Director @ Insomniac Games) - https://www.youtube.com/watch?v=rX0ItVEVjHc https://www.youtube.com/watch?v=rX0ItVEVjHc
- deleted 8y ago[deleted]
- danschuller 8y agoMike Acton works for Unity now.
- LiterallyDoge 8y agoI don't understand why this article is so angry? ECS is a great subset of OOP. Both are helpful tools where they make sense.
- learc83 8y agoECS as they are using it in this blog is about Data Oriented Design. It's not just OOP plus favoring composition over inheritance. DOD explicitly advocates separating data from behavior, and is strongly opposed to OOP in general.
- LiterallyDoge 8y agoJust so I understand you right: they're advocating global functions to operate on predictably similar data structures? If that's the case, it seems like you'd want some of them to be object-oriented, and some not.
- learc83 8y agoEach system tends to operate on different sets of data which don't tend to be very similar, and systems may operate on multiple data sets. You could build each system as an object, but you wouldn't want to store the relevant data structures within that object because other systems will likely need to use those data structures as well. The entire architecture is predicated on separating data and behavior. Yes you can build an ECS system using classes, but nothing about it fits into what you'd call OOP.
- thrower123 8y agoFor at least the last ten years, maybe fifteen, on the GameDev.net forums you haven't been able to swing a dead cat without hitting somebody going on and on about entity/component systems or pushing them as the One True Path, or trying to create their own implementation. It's probably worse now that Unity is so big. I'm not sure it is something I would pitch at beginning programmers, and there are a lot of them that wander into that, decide they are going to follow that advice, make a big mess, then wind up asking Hodgman and the handful other saintly regulars that keep that place going, to help them out.
- pjmlp 8y agoPublished in 1997, "Component Software: Beyond Object-oriented Programming", followed by "Component-Based Software Engineering: Putting the Pieces Together" in 2001. https://www.amazon.com/Component-Software-Beyond-Object-Oriented-Programming/dp/0201745720/ref=sr_1_1 https://www.amazon.com/Component-Software-Beyond-Object-Orie... https://www.amazon.com/Component-Based-Software-Engineering-Putting-Together/dp/0201704854/ref=pd_sim_14_1 https://www.amazon.com/Component-Based-Software-Engineering-... The problem is how badly many schools teach OOP paradigms, and how many frameworks abuse a specific style of OOP.
- Sharlin 8y agoI’d be very wary of hiring an ”OO” dev who can’t reasonably formulate what the SOLID principles are and why they exist.
- EliRivers 8y agoDo they have to agree with them, or just be able to name them?
- Sharlin 8y agoWell, it's definitely a plus if they can convincingly argue against any of them. They're tools, not dogma.
- jimmy1 8y agoEven Solid, like OOP is one of those concepts that has morphed more into an ideology than it needs to be with blind faith adherents https://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong https://speakerdeck.com/tastapod/why-every-element-of-solid-... I'll take someone who writes simple code that can be easily changed 101 out of 100 times over a SOLID, OOP Adherent.
- neeleshs 8y agoThat presentation basically says "write simple code". I'm not sure how is that helpful to anyone.
- jimmy1 8y agoIt's immensely helpful. Stuck in a rut designing your type hierarchies and making sure they are perfectly SOLID? STOP. Write the simplest, most clear and concise thing that works, refactor it once it gets too big to fit in your head. Not sure if your AbstractFactoryBeanProxyImplImpl is generic enough to cover all use cases? STOP. Write the simplest most clear and concise thing that works, refactor it to adapt to more problems as needed. Tired of fighting your type system because your stuck in a wheel of is-ha has-a is-a has-a? STOP. If it acts like a duck, and quacks like a duck, it is a duck! Write a duck!
- DrNuke 8y agoTo be fair it was in the late ‘90s - early ‘00s a very clean way to make communication work among teams, at a time still deeply into the non-internet era and C or Fortran oriented.
- noncoml 8y agoThe problem is not OOP, but how C++ and Java implement it. Ruby is a much nicer OOP platform.
- twic 8y agoHow so?
- noncoml 8y agoThe most important part missing IMHO is late binding.
- StillBored 8y agoPlease don't include C++ in that statement. C++ doesn't "implement" OOP in any particular way. It gives you a pile of tools which can be mix/matched with other tools in the language to create any number of paradigms. The "pure OOP" style that is so roundly criticized is just one of C++'s possible styles. The whole article is effectively about how there are other ways to use C++. I actually tend to think that much of the style he is describing (composition based) is really just what the pure OOP people used to criticize as "C with objects".
- leowoo91 8y agoOOP in game development is in good use with engines like UE4 and Godot, so it is about choice. What really matters is how comfortable you are with the way you develop the game.
- leowoo91 8y agoI don't get it when a functional programming comment gets highest score in a game programming pattern thread while a game-dev related view gets the lowest.
- gracenotes 8y agoOddly enough I've been getting into UE4 and things would be so much easier for me if the core classes were better decoupled. For instance, I'd like to have a quadraped skeleton with the ability to apply a movement vector. Unfortunately, in the Actor->Pawn->Character hierarchy, you cannot have movement (applying vectors, walk/jump/fall state) without a capsule root component - which is the only one respected for collision - so either I have to rewrite all of the movement code or somehow make the capsule vestigial and carefully maintain its state. In short, in some cases it's useful to say that a Pawn is an Actor with a set of extra features, or that a Character is a Pawn with a set of extra features, but even there, the way inheritance forces you to adapt an exact set of extra features and no others and also those features are not piecewise reusable elsewhere is a pretty big structural problem. I've already done enough arguing about OOP for one career in programming, I think, but the more I see what's out there, the more that I think the real enemy is any use of class inheritance - even the TAPL formalization of OOP uses interfaces only.
- leowoo91 8y agoI certainly agree, I ever used ECS from the beginning. Just surprised when I saw a new engine like godot follows OOP. It might be because engines are better fit but not the game itself and gets omitted easily.
- heinrichhartman 8y agoDoes anyone know of a good reference for idiomatic OO(P)? Like the Codd paper for Relational Algebra.
- arendtio 8y agoIf you use a typical IDE that comes with Squeak or VisualWorks, you can quickly inspect a lot of idiomatic code from the standard library. The most common mistake I have seen is that people who know about other programming languages, start looking at OOP as a way to separate and organize code. Instead, it starts from the other side: OOP is based on a few core concepts, and those concepts are critical to understanding OOP. The first concept is 'Everything is an object', the second might be 'Objects can receive messages'. So if you have some code: 1 + 2 It means that there is an object '1' which receives a message '+ 2'. If '1' is an Integer, Float, String or whatever might be relevant for its inner workings but if you want to understand OOP you first have to understand the concept-side of it (and ignore the implementation). Once you know the concepts, you can reason about good and bad implementation/code. You might wonder about the preachy tone, but in the beginning, it took me a few months before I understood that I was trying to understand OOP from the wrong side (at the time I was thinking in C) and I would like others to have a quicker start than I had.
- heinrichhartman 8y agoThanks for your reply. Where would you go to "to understand the concept-side of it" better? I am reasonably fluent in Java and Python, and read a lot of C/C++. So I think I have a solid understanding what OO looks like, and what concepts are involved (dynamic dispatch, polymorphism, inheritance, etc). However, there is a lot of critique about the OO models in these languages and code that is found in the wild. What I am looking for is a principled treatment, that avoids these pitfalls.
- arendtio 8y agoThe professor who taught me OOP wrote a book which I never read, but I am confident that he focuses on the concepts in the beginning: https://books.google.de/books?id=RAloBgAAQBAJ&printsec=frontcover&hl=de#v=onepage&q&f=false https://books.google.de/books?id=RAloBgAAQBAJ&printsec=front... Another good source of ebooks seems to be this page: http://stephane.ducasse.free.fr/FreeBooks/ http://stephane.ducasse.free.fr/FreeBooks/ There you can find the Blue-Book which looks like a great resource too: http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.... Some Links seem to be broken nowadays, but some content can be obtained from the archive: https://web.archive.org/web/20130319110836/http://stephane.ducasse.free.fr:80/FreeBooks/SmalltalkDesignPatternCompanion/ https://web.archive.org/web/20130319110836/http://stephane.d...
- Spearchucker 8y agoTook me a long time to grok OOP and OOD (was introduced to OOP in '91). At first I thought I knew it, and then realized I didn't. Plane into the side of the mountain, no survivors, call off the search. Which is when I really started to learn (around '96/97). And now I love it. Until I come across people who always start by defining an interface first and then think about what might follow. And dependency injection. Holy priceless collection of Etruscan snoods DI makes me want to gouge out my eyeballs with a rusty cork screw. Like I said though I love it and today my happy land is about 80% OOP and 20% everything else.
- hacker_9 8y agoDI is bad, what? So how are you writing tests then.
- tonyedgecombe 8y agoI always though dependency injection was an inevitable product of over zealous testing. As soon as someone says we need to test 100% of the code in our UI that is where you end up.
- hacker_9 8y agoNo it's just an inevitable product of 'testing'. It's a simple way to enable and disable dependencies. There is literally no better way, apart from not having any dependencies in the first place of course.
- Spearchucker 8y agoLike in procedural languages I write my own harnesses as needed. Because DI adds complexity. And for testing all DI does is make testing easier. You end up shipping all that complexity or you refactor your ship code. To be fair that might be acceptable to many in a typical corporate environment.
- vietjtnguyen 8y ago
- tomelders 8y agoIs FROOP a thing? Cos that’s what I’m doing it seems.
- beders 8y agoI think OOP is fine as long as it's the only thing you are doing and as long as it is single-threaded. Problems will occur if you need to convert the innards of your objects to data (i.e. JSON etc.), if you need to materialize objects from data (i.e. ORM) or if you need to write multi-threading safe code. If you expose things as data, just be honest about it and treat it as such. It's already out in the open, why hide it in objects again?
- kazinator 8y ago> if you need to convert the innards of your objects to data Not to mention: when you need to make objects correspond to a database.
- seanmcdirmid 8y agoOOP with threads is fine. Mutability is orthogonal to OOP anyways.
- the_af 8y ago> If you expose things as data, just be honest about it and treat it as such. It's already out in the open, why hide it in objects again? What if this exposure occurs at the boundaries of your system, or when interacting with certain libraries? Surely there's value as "mostly" handling some things as objects within your system, even if you expose their innards and maybe break their invariants at the boundaries.
- jschwartzi 8y ago> I think OOP is fine as long as you are doing it and as long as it is single-threaded. I don't really see how threading has anything to do with it. What OOP allows you to do is choose what terms you want to express your solution in. You can choose language that exposes thread-safe aspects of your problem domain without requiring the user to be aware that they are expressing things in thread-safe terms. In my last project one of the early elements of our architecture was a thread-safe message queue for each thread to receive messages from across the thread boundary. Discussions on our team involved talk of messaging and threading because those were the abstractions we chose to use to express our solution. We knew that order of access was important and so we chose to make it explicit in the language we used to express the problem. And the abstraction we chose allowed us to hide the details of the problem in such a way that we did not have to worry about memory protection as long as we were consistently using the architecture we built. That was a concern of the messaging system's maintainer. We could just as easily have chosen rows and columns and operators on such and expressed the same solution in those terms. What mattered to us was making sense of the problem, domain and solution. It really doesn't matter which paradigm you use. What matters more is that you express your solution in terms that are consistent with the problem domain, and that you actually make an effort to understand the problem you're trying to solve well enough to express the solution. Anything beyond that is just sugar.
- spacesarebetter 8y agoand the website is dead as well
- jf- 8y agoSoftware developers are systematisers by default. We tend to value complexity for it’s own sake, hence the over-engineering common to software projects. The methodologies we use fall victim to the same tendency. We build complex, rigid rule sets that are claimed to improve software or development speed or whatever else, without any actual empirical evidence that these claims are true. All you can really do is try to be knowledgeable about the methodologies, use the right tool for the right job, and try to keep things as simple as possible. And don’t subscribe to anybody’s dogma.
- legulere 8y agoThe full quote by Einstein is: “Make things as simple as possible, but not simpler.” I think the second part is important to not overshoot.
- jf- 8y agoWell I wasn’t quoting Einstein, but sure. I would err on the side of less rather than more.
- ken 8y ago> use the right tool for the right job, and try to keep things as simple as possible Now all we need to do is get the field to agree on universally applicable definitions of "right tool" and "simple", and never change any requirement after any technical decisions have been made, and we'll be all set! I had a manager who used the term "ice cream" for phrases like this that sound good (everybody loves it!) but don't help drive any useful conversations or decisions. Should we use the right tool for the job, or the wrong one? Let's use the right one! OK, are we all agreed? Great! It's unanimous. Next issue. Unfortunately, the 5 people sitting around the table each have a completely different conception of what this means, so we're no closer to a decision than when we started. It's simply not a useful guide or metric. I think it's mostly code for "be quiet and do as I say".
- jf- 8y agoDepends on how needlessly argumentative your team is. Generally you can reach a consensus through discussion, example and experimentation. We do have intuition, generally we know what simple looks like when we see it, likewise we recognise what the right tool looks like as we try several. Do you want a checklist for this kind of thing? You’re not going to get one. You have to use your own judgement. Possibly you’ve fallen victim to being on teams where ego dominates, and members refuse to seek the best option unless they came up with it themselves.
- deleted 8y ago[deleted]
- ilovecaching 8y agoBecoming a professional Haskell and Erlang developer really shifted my view on OOP (let OOP denote class based OOP as found in Java or C++). In my view, OOP is prove a poor model for computation, and the result has been that OO code is almost always significantly more complex and error prone than an equivalent computation written in a concurrent, functional, or structured paradigm. Recent trends in language design (see Rust, Go, Elixir) also seem to be abandoning OOP in favor of other models as well. OOP provides competing ways of abstracting behavior that in Haskell we can model with type parameters and constraints. Objects are not truly encapsulated in the way Erlang processes are and a poor fit for SMP. Objects also pathologically hide data in attempt to manage mutability, making it impossible to reason about the memory layout of the program. All in all, OOP is a toolkit for building bad abstractions: abstractions that do not easily model computation, that hide data, and has tended to create overly complex solutions to problems that are often full of errors that a language focused more on type expressivity could catch at compile time.
- Chabs 8y agoI think you are conflating OOP with type erasure. Most OOP languages support type erasure (including rust!), but that's far from all there is to it.
- ilovecaching 8y agoHow so? I believe I was addressing the fundamentals of OOP: Classes, methods, inheritance, overloading, visibility, etc. Also, Rust, while allowing the assigning of behavior to a type, is explicitly not OOP. Check it's Wikipedia page (which doesn't include OOP in the list of paradigms) and the O'Reilly book (which says Rust isn't OOP).
- Chabs 8y agoI didn't mean rust was fundamentally OOP, but that rust implements, through runtime traits, exactly the behavior you are criticizing OOP for. Sorry about that
- jorgeleo 8y ago"Before you decide that OOP is shit and ECS is great, stop and learn OOD (to know how to use OOP properly) and learn relational (to know how to use ECS properly too)." This is why DDD needs to be in place before using OOP
- LolNoGenerics 8y agoSo DDD is now a prerequiste to use OOP? Wow!
- LolNoGenerics 8y ago> This code may be typical of OOP in the wild, but as above, it breaks all sorts of core OO rules, so it should not all all be considered traditional. This argument drives me nuts. A simple OOP environment can be quite easy to grasp and (mis)use. Following all the golden rules and principles that SOLID et al call for, are comparabily hard to internalize. A rookie can only fail and has to collect, choose and study all the wisdom over the years until he becomes a master. To that point he will create OO code that will break untold rules. Ruling the majority of OO code out there as "bad" is hubris and ignores reality. It is easy to do OOP wrong and hard to get it right. This imbalance is proof enough for me that we don't know what we are doing, just justifing. (Yes this may apply to other paradigms as well)
- dkarl 8y agoRuling the majority of OO code out there as "bad" is hubris and ignores reality. It is easy to do OOP wrong and hard to get it right. It wasn't the inherent nature of OOP that caused that terrible style to become dominant. It's a style that was actively taught and promoted since at least the mid-1990s. It was taught, and taken for granted, that objects were containers for mutable values. Deep inheritance hierarchies were taught as the norm, not the exception. Java was built around this model and then became one of the most popular programming languages in industry, and learning materials for Java reinforced the style. Everyone interviewing for a Java programming position from the late 1990s through the mid 2000s had to learn special jargon related to this style and regurgitate it in interviews. We're suffering through a hangover from decades of this horrible version of OOP being promoted as the "right" way to write software in industry and academia.
- ben509 8y agoThis is the "you're holding it wrong" defense of OOP. Of SOLID, S, O, I and D are rehashing structured programming design principles. LSP is peculiar to it, and not an unreasonable way of thinking of objects, but I don't see people struggling to figure out how to come up with workable class hierarchies. The point of objects was that they were intuitive and easy, and where it tends to fall apart is in the details. It's often small tasks like writing an equality operator correctly that are absurdly complicated[1]. And while we can construct reasonable class hierarchies, the interaction becomes a bear and the bugs are subtle and confusing. What I see in OOP programming is that people avoid various idioms or patch around them because they don't trust their tools. I think the problem with most OOP languages is that some high-level concepts like inheritance were constrained by very low-level implementations, and they often tried to glom several ideas together. There's no "object algebra" even 40 years in. In C-like languages, objects are using a "struct and vtable in the heap" model. In dynamic languages, they're using the "type instance and a hashtable in the heap" model. Then they typically declare that a value is really a variable, unless it's an atom, and often other weird asymmetries like "the bottom type actually does have a value which is 'null'" and, of course, whatever weirdness they pick up such as floating point. Those constructs are then overused; this problem is especially apparent in Java where "everything is an object" means that your class becomes your tuple type, and if you want to combine two tuple types you're going to do that via inheritance. In most of them, you don't have a proper discriminated union, so all the stuff you'd do with sum and product types you now have to shoehorn into classes whether it makes sense or not. It all sort of works, but the reason OOP languages keep adopting non-OOP features is that it doesn't work very well. [1]: http://jtechies.blogspot.com/2012/07/item-8-obey-general-contract-when.html http://jtechies.blogspot.com/2012/07/item-8-obey-general-con...
- zdmc 8y agoA good heuristic: if you’re not dealing with “state” (i.e., Games, DB ORM, Reinforcement Learning), then don’t use OOP
- lerno 8y agoReally? I’d say the accidental distribution of state across objects due to cross cutting concerns is exactly where OO breaks down for me.
- Hodgman 8y agoIf cross-cutting concerns are making your architecture unwieldy, you likely haven't used composition enough / are doing OOP the bad way (tm).
- lerno 8y agoNo, some logic simply isn’t cleanly decomposable, plus the main problem here is that objects lets you get away with implicit state (e.g. if (this.x == 0) doA() else doB(); ) for long enough that when you start realizing you need explicit state, it’s usually distributed quite a bit.
- bribri 8y agoI completely agree. Use it carefully if you need it but it shouldn't be the default.
- p2t2p 8y agoAll my attempts to jump off OOP train break at exact same moment when I try to write a unit test. Closure: or, simply use this monstrous component pattern when 70% of your code is boilerplate or hack into namespaces and override functions in them in runtime. And don’t forget to do it in right order! JavaScript: yeah, simply re-define ‘require’ before importing dependencies in tests. Yeah, do it in right order. Recent example - I was researching how to mock calls to functions in packages in go... Well, the best thing you can do is to have package private variable, assign function to it and use it throughout the code so you can swap it with mock/stub in a test. There is none of that bs when I write Java or C#. I have a mechanism to decouple contracts from implementations - interfaces. I have mechanism to supply dependencies to modules - it’s called constructor parameters. I can replace implementations easily with mocks or stubs in tests without target even noticing that. Can somebody provide me with an example of this kind of decoupling achieved in other paradigms _without_ hacking the runtime of a language or ugly tricks like in go case?
- ilovecaching 8y agoGo interfaces, Rust traits, and Haskell typeclasses and simple parameters do exactly what you ask. In fact, it's harder to mock/stub in OOP than it is in FP by the nature of FP making all dependencies always explicit. Being able to use a 'property' in the body of the functions means you're now relying on a side effect that will have to be magically mocked. In OOP, type signatures tend to lie. Not so true for FP.
- p2t2p 8y agoThe problem with simple parameters is that I need to drag all of my low level stuff through all of the layers of the application. I one was imagining a framework for Closure that would do something like that: - you define a bunch of functions. Some of this functions depend on other of those functions. - for dependent ones you define parameters and tag them somehow - you call this functions without mentioning those tagged parameters - during the startup the framework takes over and does partial application, generating functions with same names but without tagged parameters, so you kinda have your dependencies injected. I don’t know if this sounds too crazy or too incorrect for Closure’s paradigm.
- SolarNet 8y agoEverything here is bad and wrong on so many levels. It's hard to even wrap my head around the amount of wrong going on everywhere here. The initial Object Oriented (OO) code - as partially demonstrated by the author, and more succinctly by the grand-author - is badly designed. In the grand-author's slides they remove a number of these stupidities, which the author appears to ignore (both for final performance comparisons and for understanding why they were even there). Notably they (the grand author) originally built a reflection (runtime type) system [0] directly into their game objects (application level code). This of course means they then ended up fighting their programming language over the performance of this as they attempted to use and improve it. The author's improved code is also a total failure. He removes a significant amount of the flexibility in the original system, which was a requirement of the problem space. By removing features he gains a significant amount of performance (in actuality about 2x - not 10x - compared to the grand author's slides). The lack of understanding why those features were there in the first place demonstrates he doesn't understand the actual design space of the toy demonstration code. It also demonstrates he failed to read the grand-author's slides where they go through some of these changes and why they aren't viable. The author also fails to even discuss the Entity Component System (ECS) which it should be noted is still faster (and feature intact!) than the author's code. I cannot be more emphatic on that point, an ECS is a solution to the performance of run-time composition problems, and it still worked even better than an attempt to do the OO solution right (again by removing features!). Though the author makes an excellent point about how most ECS solutions tend to fight the programming system they are in, he doesn't really explain or demonstrate it. What the grand-author did wrong here (though probably actually not in their talk considering who they work for) is not point out that the ECS should be part of one's programming tool to be most effective. Notably the ECS optimization should be part of one's programming language [1] (a game engine's programming language - like Unity's - would count). Point is this author is very wrong and does not understand design (in general) nor the entity component system pattern in specific at all. The grand author's example code base is disingenuous of actual OO principles, and does not provide reasonable advice on how to deploy an ECS. Oh and they both got wrong that ECS solutions should be part of one's programming tool, not application space. [0] Engines are often attempting to solve a sufficiently complex problem space that they require runtime type systems. This is not something one can avoid unless writing a bespoke "engine" for a single game. [1] Unless your programming language is sufficiently advanced to allow creating - effectively - compiled code at runtime as a generalized library. Which C++ is because of template meta-programming, but the included example code is not.
- bribri 8y agoI can't think of any oop abstractions that I prefer to functional abstractions. If you really need has-a is-a relationships or mutability you can get them a la carte with a language like Clojure, but they're not deeply baked in to the language nor the encouraged pattern for extending code.
- agentultra 8y agoFor me, whenever someone invokes the GoF or SOLID, I’m reminded of the Brothers Grimm. It’s programming by folklore. That’s all the GoF did: they went out into the world and tried to observe how programmers were structuring their programs. And they seemed particularly interested in programmers using OOP. All of these principles have very little basis or formal definition. Bertrand Meyer did make some headway with Eiffel. But the type systems are so weak and the lack of formal semantics makes all of these discussions a bit of hand waving and bike shedding. At least the DOD folks have some guiding philosophy and are trying to optimize the design of programs to account for memory latency of modern hardware architectures. The OOP defenders are basing their argument on hot air and hand waving. There are more interesting languages these days with better designs. Ones that are based on better theories in my opinion. OOP will be around for a long time if only because it has so many adherents and people will be stubborn to change if history has anything to say about it.
- wolfspider 8y agoThis is a pretty good discussion and I’m surprised that while discussing OOP not much was brought up in the way of managing private versus shared memory which I think depending on the platform is not as universal as we all hoped it would be by now. Marshalling objects with pointers accessing vtables over uneven terrain is how it goes down. I think here is a good example: https://trac.webkit.org/wiki/WebKitIDL https://trac.webkit.org/wiki/WebKitIDL And to further that point there is no more Safari on Windows for this reason among many others. Remember MemMaker? It’s crazy there were so few applications we managed some of the memory ourselves but it worked very well didn’t it? OOP really took off back then too and then memory utilities were not needed and didn’t last too long. The convenience of not worrying about it is one of the many things OOP was able to solve as it advanced. It is still pulling off the same tricks today in a much more complex and metered way. OOP does so much more than just this of course but the solutions developed with it for managing memory are intense and as much art as science. So we should question it and many paradigms to make this better. A mentor of mine when explaining this would compare it to juggling...and then proceed to actually start juggling while talking about his code. He’d stop and look up, just pause, and say that’s all we are doing here just juggling.