Комментарии:
Inheritance is nice when it makes sense, as in interfacing. My last job I worked at, I was the programmer making digital signage work for a company. Part of that was turning on and off TVs and making sure they were all on the appropriate input for the content we were sending. Covering all of Samsung, LG, Sharp, and a couple of others, all with different serial commands to send and different timings, creating a different routine to work with each in the main program would have ballooned things out of control. Instead, define a TV with functions to return current status, set TV power and input states, and then define child types inheriting those functions which implement the proper method of interacting with those individual models.
End result? Define a variable of type TV, tvVar.open(), tvVar.power("on"), tvVar.input("HDMI1").
Doesn't matter that it's Samsung or Sharp, even if you mix the two models at one site, as long as the computer knows what index of TV is what model, it can control it with generic commands from a parent class type. I don't agree with five levels of inheritance, but there is a time and a place for even grandparent classes.
Getters and setters CAN be good though, when you want to enforce particular limits or perform sanity checks on access. You can also put DB access in getters and setters to make a complex piece of code into something easier to read. I agree though, if all you're doing is trying to access the value of a class member and nothing else, getters/setters are stupid.
Because I'm a game dev I guess I like oop more than function and contradict Aly idk what is a function programing
My brain is wired in oop, like let's say I wanna make crafting game, instead of manually setting up recipe for every type of wood to make a door in a minecraft clone I can just check if the object inherit wood, so I can make a wood object with things all wood blocks would have, like is flammable, can u make doors, what recipes use it and I can make the children mahogony wood, pine wood, oak wood inherit the base attribute and just add the specific attribute, like if I want to differentiate hard wood from soft wood this would be specific, but you can make a torch with either
OOPs? more like OOPS!
ОтветитьProper OOP looks like someone wrote Lisp.
ОтветитьThe problem with inheritance is that it has to be 100% correct - if somewhere in the chain something is only 99% what its ancestor was, the hierarchy falls apart - and there's no way to predit on step 1 what step 17 will look like
Also, even if technically 100% correct, it's not always useful, e.g. "square is a rectangle" example, where even if it's technically true, inheritence wouldn't work well for it
There is a saying, there are no solutions, only trade-offs. The issue with programming is people always try to find the perfect solution because deciding on trade-offs all the time is tiring. Everything OOP says can be useful in a specific context. Say you are reading lua tables in a game you are working on that your lua script provided, do you really need encapsulation there? On the other hand, async asset loader you have imo requires encapsulation.
The differentiator here I think is state vs. data. It depends on whose job is managing the data. For asset loader, you just provide inputs and rest are handled by internal functionality; so it has a internal data: state. But, say you have 500 enemies that path towards the player character. That's game loop's responsibility to manage that pathing, so encapsulating stuff about that in enemy makes it harder to reason about because that's a POD the game loop needs to modify, in a sense part of "game loop state". So, don't write clever code, write code that's easy to refactor and reason about. That doesn't mean stupid or simple code imo and requires experience to write it out. Make everything else opt-in. Only add other abstractions, like encapsulation when you need it, just like rust's mut, or smart pointers' Box, Rc etc.
I think prime is a little confused sometimes about some terms. For example he says he hasn't used a nice inheritance hierarchy but then says I love interfaces. It's the same thing dawg. Its just an interaction in the form of a pointer. The only difference between and interface and a class is that in most cases the interface doesn't have any data only pure virtual methods. But nonetheless, I think OO is great and I think most people think so. There are just some things all people can agree are bad and everyone hates them but you don't hate OO.
ОтветитьI'm really sick and tired of people using inheritance to share behaviour. You should not!
It is for identity. I recently posted a tweet thread on it as well.
If you want to share behavior, compose or delegate.
Inheritance is for identity. To answer the question "Human is a Animal?"
As someone who's programmed in multiple paradigms, my favorite paradigm is whatever paradigm solves my problem for me.
I have no qualms mixing functional with OOP. It all depends on what the problem is.
Computed properties and magical getters & setters was the thing I hated the most about ruby.
I'm glad the last time I wrote ruby was many years ago. :)
The only place where having getters and setters instead of just plain public properties makes sense is when some sort of lazy-loading might be involved and the getter would not be just returning some field already present in the class, but do some additional computation before actually returning a value. Another example might be properties that want to allow sub-classes to return a different value when the property is being read, although I personally don't think this is a great way of designing things
ОтветитьI like object oriented functional OOF.
ОтветитьDoes structural typing still let you explicitly implement some of the interfaces? I like purposefully implementing an interface and being forced to implement the necessary methods by the compiler
ОтветитьI'm sick of these bloggers promoting the idea of being stupid. That's what they really say: "oop is bad. dont use oop, be stupid!"
If you do not understand and do not want to understand OOP, this does not mean that OOP is bad.
“I'm dumb and that makes me productive,” says Prime. I'll tell you one secret. Being productive is not the same as writing good maintainable code.
I feel like you should do everything as functional as possible, apart from very straightforward classes to represent an actual object (JSON object for instance), and only allow the deeper OOP patterns to come in when they are your last option and also can provide a really semantically explicit model of what it is that your code is supposed to be doing, and what new future code needs to do to extend it.
ОтветитьWhy do we ignore Scala
Ответитьgo is just works, no fancy concepts, easy syntax, good standard library, fast...
ОтветитьThe main thing with OOP is that it is a ANALYSIS and DESIGN framework. Meaning, one designs system visualizing key Objects, whereas one can also (not mutually exclusively) map the FP design. As a communication domain it provides most of its value
About Inheritance.
- Extend an Interface: YES. and use the Interface type everywhere to fight coupling, and make the system broadly upgradable for the AgEs.
- Extend a Class& Abstract classes: No. Stop it. Please. Never. I have yet to be able to extend a class, even 6 months later, without fighting with the base class.
anyway. 2 cents
Liskov Substitution principle: "If it looks like a duck, quacks like a duck, but needs batteries, you've got a wrong abstraction"
ОтветитьWhy programming has to be so complex?
ОтветитьConcepts are in C++20
ОтветитьOOP is like Communism. In theory it's great but everyone seems to do it wrong every single time.
ОтветитьEmpty should be is empty
ОтветитьIf I want to provide behaviours for example with a bird I just use interfaces. IBird, IFlyingbird, IDrawable, ISerializable etc. Avoids the nested inheritance trees but provides the same benefits and makes DI, testing etc easier
ОтветитьC has header file as abstraction and switch the pointer as polymorphism
Ответитьas a java engineer i can't understand a word this guy says
ОтветитьI use very little inheritance since it's often used just to reuse the same methods. Always composition over inheritance. I see many people fail here.
Most people don't understand Domain Objects either. Domain Objects are not:
- using POPO/POJO/POCO objects
- splitting your entities in categories.
- using a data mapper as ORM
The reason why people do think this has to do with that we use MVC where applying domain objects would result in 3 objects per domain (for request/validation, storing and for response/view). The result is that people try to move these 3 objects into one domain object and use things like decorators/attributes/annotations to apply to either all 3 of them.
communism cannot work, even if you do it correctly
ОтветитьRust is best of both world.
Ever notice how const fn have no side effects? Try it, you cant even use &mut.
I've created shallow and broad type hierarchies that didn't run afoul of Liskov's substitution principle.
ОтветитьMan really wrote an essay about how actually Rust is OOP and then never addressed the fact that non-interface inheritance shouldn't exist or why "state with methods" and "modules" should be the same thing.
ОтветитьIMO getters are great, but setters are bad. Every time i had to use a setter, it was ugly.
But getters are just a convenient way of achieving immutability.
Talking from Java perspective, of course there is final keyword, but sometimes it's a bit inconvenient to use (a bit too restrictive), but having private properties with getters is more flexible
C# basic here: When using WPF with data binding, the required INotifyPropertyChanged pattern requires property getters and setters... and it's a lot of boilerplate... ugh
Ответить"We'll C, we'll C"
ОтветитьPeople (yes, including you Primeagen) saying "OOP sucks" most often mean "inheritance sucks", whilst failing to understand that inheritance is a tiny subset of OOP.
Ответить"Functional Bros"
ОтветитьAn object is an example of a class. Without writing a class that object change it's name and it's called function. Weeks later on you start to believe you are furry.
Ответитьbig OOF
Ответитьdeez nuts oriented programming
ОтветитьOOP is coupling data tightly to the functions that always act on that data. that's it.
Ответитьuse isempty to describe the behavior of validating length, empty infers that you are creating an empty instance
ОтветитьOn structural vs nominal typing/the usage of explicit traits:
I would say the biggest upside of traits is that it has namespacing builtin.
That way you can implement multiple traits with the same method names independently, which might otherwise be a big problem.
Structural typing is scary as you can accidentally implement an interface you did not expect/want to implement. If it was actually good, c++ would not use it.
ОтветитьVery much against computed properties/property observers/ whatever you wanna call it. You're calling a method, you're just lying about it at the call sight. It's hidden control flow for no benefit.
Ответить