The Problem With Object Oriented Programming

preview_player
Показать описание
This video points out the issues and problems with inheritance as a primary object-oriented design pattern. Inheritance, polymorphism, and virtual functions seem complex. But once mastered, they tend to become a primary tool. However, replacing inheritance with composition leads to a more flexible and elegant design.
Рекомендации по теме
Комментарии
Автор

"UML is for people that can't program". I laughed so much at this and I totally agree with you.

vladsbaking
Автор

Take input out of ship, have enemy inherit ship, and have a new class called PlayerShip also inherit from ship and including Input. Look I can do object oriented, you want a UML diagram? I can do that too! Hire me! HIRE
So true. Especially the "it's hard so we have to use it everywhere", that's the mindset I had from Uni. It's kinda this feeling of "I learned this cool thing, I have to use it everywhere".

tomwhitcombe
Автор

Why is this not called "The problem with OOP teachers"? :-S Also if you wanted inheritance, move the velocity and boundary in front of the player and enemy ships... But the ammount of "code smells". *shiver*

ThePlacehole
Автор

I always get that feeling that I used to accomplish more when I didn't grasp OO.

klokibril
Автор

Lmao this is an EPIC video! Very funny, very informative! THANK YOU SO MUCH! - You hit my problems VERY accurately! I suffer a lot from this in Unity!

vexedev
Автор

Looking for the next vid in the series? Can't seem to find it, has it been released yet?

michaelleppan
Автор

So interface segregation (the I from SOLID) partially addresses this, but you just have to implement the interfaces, you don't get to inherit from them, unless you do make another class that implements each of those that you need...


I think the hatred of UML is a little misplaced, yes, there was a time when people seriously thought people were going to start "programming in UML", that wasn't a joke, but it is a standard and pretty good way to communicate about analysis and design ideas in those phases. Since people are visually oriented, the alternative was pre-UML when you had 269 different ways of drawing the same dang things -- that was worse, not better.

jvsnyc
Автор

don't advocate oop, but you can inherit enemy from ship and reimplement input to work with AI... so it kinda weak...

oberguga
Автор

As much as I agree that inheritance is dangerous or hard at times, this does not at all represent any problems. You just move Velocity and Boundary into another abstract class, say MovingObject. The problem would occur only if there was an entity that had non shared features of both ship ANDand LERPer, in which case concrete class inheritance would be impossible and you would have to use interfaces instead.

shoqed
Автор

Make gameobject final and have a field for a movement class instance which can be redefined for any type of moving object, and could just be a function pointer.

disdroid
Автор

Why derive _Enemy_ from _GameObject_, if it's also a ship?!
If it's not, you're missing an intermediate _MovableObject_ in between _GameObject_ and _Ship_, so derive _Enemy_, _Ship_ and some maybe _Asteroid_ from _MovableObject_

mireazma
Автор

The Enemy would be inherited from the ship class, while the ship has to be bond to a player the enemy would bond to the AI for the input, the AI is a own class, that sents the input to the ship of the enemy. This example is a bad try to convince people that OOP is in general bad. It is just about the people who choice wrong design pattern for a solution. So, it will be also about procedural programming, bad architect, bad program. If you have the Objects GameObject, LERPer, Ship, Player and AI, the example would fit again perfectly to prove why you should do a good planning with the tools in your programming toolkit like UMLs, the Player and AI could even be inherited from another class. Programming is not just writing code, it is also to think about a good solution for a problem.

SanYueTong
Автор

Below is me working out my thoughts on OOP in a concrete way, and it goes on way longer than is appropriate for a YouTube comment. TL;DR: OOP is a reasonable way to organise your code, and it can make maintenance easier if it is correct. Making OOP programs correct, however, is not easy.

I'm not much of a programmer, but I've been watching a lot of videos for and against OOP lately, and I think I've got a few insights I think I've gained about the act of programming in OOP.

The first and biggest for me is that OOP is almost misnamed. The core concept is not objects but messages. The idea is that one part of your program should not make any changes to any other part, but it should make requests and the other part should decide what to do with that. This is encapsulation, and objects facilitate this.

But encapsulation is more than just separating things into objects and running functions by calling Object.Method instead of calling function().

If taking out ObjectB and replacing it with equivalent ObjectC (keeping the same signature) breaks ObjectA you've probably screwed this part up. If ObjectA requires something specific inside ObjectB other than a place to send its message, you're coupling rather than decoupling. The whole point of message passage between ObjectA is decoupling.

This means it's a hell of a lot harder to program correctly with objects than it might seem, and you probably can't write a program of any size without breaking encapsulation in at least a few places in your program.

The next insight followed along after this, and it's the way we model objects. This is closely related to what you talk about in the video. I think most of the time we model objects backwards.

"Is a" and "has a" don't quite hit the target. What matters is what they do, much more than what they are.

All ships move and perform some action - probably shoot, but it doesn't have to be. If they do this, they are a ship. Since they move, they must have a location. So your base class only has only three elements: position, move, and act. This can be inherited with immunity, with no overlap with a non-ship object.

Now, to make this more general you should probably pull out the movement and position into a more fundamental object called mobileObject, and have Ship inherit that rather than Ship be your base class, because you might want something that acts like a ship but conceptually is not a ship, like a flying spaghetti monster.

Notice that after you make that name change to mobileObject it's a lot more clear what is important about this thing. You also get things like particles completely free: particles just inherit the base mobileObject class and none of the ship features.

It's absolutely critical, though, that things be correctly categorized for them to be decoupled. It's not easy. Another classic example of this that too me a bit of chewing on to figure out where it went wrong (in an afternoon to be fair to OOP) is the printer - scanner - copier problem.

Printer prints, scanner scans, both are powered devices. Now you want to add a copier. A copier scans and prints, so it inherits scanner and printer. Uh oh. Now you're inheriting powered devices from two sources.

Assuming your compiler doesn't just blow up, what if one of the parents overloads a method? Which one does it use? Regardless of how the language handles it, this might not be the behavior you intend!

The answer of course I'd that these objects are miscategorized. Printers are not fundamental to printing. We had printing presses long before we had electricity, so why is printing tied to powered devices?

The same with scanning. Analog cameras operate on the same principle as electronic scanners, yet they should clearly not inherit from the scanner class.

She solution is to break out scanning and printing from powered devices. Scanners scan, printers print. An electronic scanner inherits scanner and powered devices, an electronic printer inherits printing and powered devices, and a copier inherits scanning, printing, and powered devices.

The idea is to make large pieces from small pieces of smaller pieces. If your pieces are too big you run into overlapping responsibilities and your pieces become brittle.

OOP is a reasonable way to organize your code to make it understandable and therefore more maintainable, but it's no silver bullet. It takes careful consideration at every stage.

jeffwells
Автор

Can't interfaces solve this problem?

vexedev
Автор

maybe have a "MovingGameObject" class that only Ship and Enemy inherit? the MovingGameObject inherits from GameObject and adds to it velocity etc. :)

bashar
Автор

You could "just" do some refactoring, and make a new common base class for the ship and the enemy which in turn had the game class as base class.

oysteinsoreide
Автор

was unable to really go to that place, found pictures but if i put that page it go to sesame street.

stelarfox
Автор

My solution: make everything public and use it like a more convenient header file.

mattr
Автор

what are you using to make those diagrams and shapes? - what do you usually use to make plans, diagrams, and class designs? I recently knew about inkscape, kinda cool.

vexedev
Автор

Object oriented programming has wrecked the programming industry...

mjsanchez