Composition Vs Inheritance - Why You Should Stop Using Inheritance

แชร์
ฝัง
  • เผยแพร่เมื่อ 29 ก.ย. 2024

ความคิดเห็น • 414

  • @ErrorDebug
    @ErrorDebug 4 ปีที่แล้ว +140

    its all good but i dont think shark can walk

    • @byambaaerdene2127
      @byambaaerdene2127 4 ปีที่แล้ว +16

      Watch sharknado and be entertai, i mean educated. There you will see sharks not only ... but can fly too.

    • @jasonleelawlight
      @jasonleelawlight 4 ปีที่แล้ว +4

      your comment is the best haha

    • @skaruts
      @skaruts 4 ปีที่แล้ว +7

      That's actually an example of another problem with inheritance that he neglected to mention: you end up with classes with needless functionality. And this is a more prevalent problem than it may seem.

    • @bluesky_10
      @bluesky_10 3 ปีที่แล้ว

      Lol. this shark is monster bro not the usual shark (beautiful one)

    • @DigitalAlchemyst
      @DigitalAlchemyst 7 วันที่ผ่านมา

      My brother please google roboto shark legs and come fix your comment ;)

  • @redcrafterlppa303
    @redcrafterlppa303 ปีที่แล้ว +4

    You described a perfect case for interfaces. An interface describes a functionality multiple classes might have. Like Flying or Swimming. But you solved it with an unreadable mess of lose functions and higher order function like objects. This is not only bad code in every way but also extremely wasteful. If everyone would write code like this every website would take minutes to load and code maintainability wouldn't even be considered and everyone would need to rewrite everything constantly since nobody understands a mess like this.
    This is a proper way to solve this:
    interface Walk {
    function walk();
    }
    interface Attack {
    function attack();
    }
    interface Fly {
    function fly();
    }
    interface Swim {
    function swim();
    }
    class Monster implements Attack, Walk {
    function attack() {
    ...
    }
    function walk() {
    ...
    }
    }
    class FlyingMonster extends Monster implements Fly {
    function fly() {
    ...
    }
    }
    class FlyingSwimmingMonster extends Monster implements Fly, Swim {
    function fly() {
    ...
    }
    function swim() {
    ...
    }
    }
    This is a clean solution solving the problem of inflexibility of classes. Also the example is flawed in its core. The implementation of 2 flying monster will in general be different anyway so there is no code duplicated. And if there is shared code it is an implementation detail and should be extracted into a hidden helper function. Inheritance and composition describe public apis and are designed to describe relationships between objects. They aren't meant to simply deduplicate code. Code deduplication is a side effect of a clean code structure.

    • @廖偉帆-v1o
      @廖偉帆-v1o วันที่ผ่านมา

      JS doesn't have interface, which only exists in TS.

  • @Nerffye
    @Nerffye 4 ปีที่แล้ว +5

    I just discovered your channel and I must say you have a great way of explaining things.
    Thank you for excellent work ♥

  • @songofyesterday
    @songofyesterday 2 ปีที่แล้ว

    I feel like composition could be more secure now that I you see explain it, if we inherit a monster class and it could do things that we forgot existed in that class, then we're breaking least privilege principle in security...with composition, you have to tell what that monster can do. It sure looks easier to read too. I'm learning Go right now, newb, but liking this idea of composition over inheritance.

  • @ayushvida
    @ayushvida 3 ปีที่แล้ว

    This guy does not blink

  • @yackawaytube
    @yackawaytube 4 ปีที่แล้ว +1

    In OOP, implementation inheritance is almost always a bad idea. Complex behavior should be derived from composition of simple components, not via implementation inheritance. I learned that first year out of college.
    The "template method" design pattern is an attempt to deal with a limited case of this problem btw.

    • @aammssaamm
      @aammssaamm 4 ปีที่แล้ว

      It's still an inheritance but of another class which represents behaviour itself :)

  • @Dev-Siri
    @Dev-Siri ปีที่แล้ว

    Well atleast in Typescript
    class FlyingAndSwimmingMonster extends Monster implements FlyingMonster, SwimmingMonster {
    constructor( ) {
    super( );
    }
    }

  • @davitjanashia9344
    @davitjanashia9344 2 ปีที่แล้ว

    Great video thank you... Can you recommend some useful materials on the topic?

  • @haidernaqvi87
    @haidernaqvi87 4 ปีที่แล้ว +1

    Stop using inheritance also means stop using Abstract classes?? As an abstract class is nothing without being inherited.

  • @giorgiobarchiesi5003
    @giorgiobarchiesi5003 ปีที่แล้ว

    The example shows a situation that would require multiple inheritance, and is usually solved with composition in languages that only support single inheritance. So, no surprise to me. Thanks anyway.

  • @greggreenhaw
    @greggreenhaw ปีที่แล้ว

    Prototypes use does not produce copies of all your functions that approving does it’s inefficient

  • @Gvnrae
    @Gvnrae 4 ปีที่แล้ว

    Dude you are awesome

  • @marco8673
    @marco8673 4 ปีที่แล้ว +1

    isn't this like the strategy pattern?

  • @ajeetworking
    @ajeetworking 4 ปีที่แล้ว +297

    JavaScripts (functional): missing something, lets add Classes
    JavaScript(classes): you know what, Classes sucks back to functional

    • @christianmartinez2179
      @christianmartinez2179 4 ปีที่แล้ว +29

      You know what? JavaScript sucks let's go back to bytecode (WAS)

    • @yackawaytube
      @yackawaytube 4 ปีที่แล้ว +60

      Classes don't suck if you use them right. Every tool solves a specific class of problems - pardon the pun.

    • @TroenderTass
      @TroenderTass 4 ปีที่แล้ว +12

      @@yackawaytube Compared to not having classes, yeah classes suck. Most of the time, you just don't need that fucking class. I hardly any class solution that couldn't be solved just as efficient with a functional module for instance. There is just no need for them, what so ever.

    • @thebe5twon-minecraftbikera979
      @thebe5twon-minecraftbikera979 3 ปีที่แล้ว +5

      @@TroenderTass Well, that would likely be because classes are just a nice way of writing a constructor function and prototype functions. Prototype functions are important for memory management because you aren’t making new function objects in memory every time you make a new object. The issue I have with this video is he isn’t even making the same thing as a class that can swim and fly because each time he wants to let the monster swim or fly it’s a new function in the object, not a function in the prototype object.

    • @TroenderTass
      @TroenderTass 3 ปีที่แล้ว +2

      @@thebe5twon-minecraftbikera979 You are disgussing something very different than me. A class is also a wide and general concept outside javascript constructor functions, and in general being able to create functions as an independant snippet of code outside the constraints of an object is alot more powerful and efficient than having to traverse and be constrained by a class hiarchy like languages like java. If you by any means find it easier to use those class based constructs over functional supporting languages, than you really are stuck in a convoluted way of thinking, and not willing to expant your mind into more productive code. A js class isn't really a class, and is not a really what i had in mind when i said that you in general don't need a fucking class. Classes are really overused stupids concepts, outside those few cases where they can be handy, wich are rare.

  • @Valyssi
    @Valyssi 2 ปีที่แล้ว +69

    Although many people would argue memory isn't much of an issue in most code except a few specific use cases, I think it should still be mentioned in a video like this. When you're creating functions in this way, without prototypal inheritance, you're creating separate functions for each object instance. With prototypes you'd only have to create them once. This can impact your memory usage, although this is generally only an issue for very large functions or if you're creating thousands of instances per frame, or if you continuously add instances that aren't removed from memory. Those are relatively rare use cases. Most often you'll be creating singletons or under 100 instances of an object accessible in any given frame, in which case the maintainability and expandability of composition should be preferred. However, if you ever did have to switch to prototypal inheritance for performance, you'd have to change your entire implementation.

    • @arcadeduo7101
      @arcadeduo7101 ปีที่แล้ว

      It is possible to manually create an inheritance prototype by using a constructor function and manually setting the methods as prototype methods, right?

    • @vukkulvar9769
      @vukkulvar9769 ปีที่แล้ว +2

      @@arcadeduo7101 You can. You create every method as a function, and then you attach it to the prototype of the object / class.
      // Example
      const myPrototype = { foo: foo };
      const myOtherPrototype = { foo: foo };
      Object.setPrototypeOf(myObject, myPrototype);
      Object.setPrototypeOf(myOtherObject, myOtherPrototype);
      // And if you want to combine prototypes freely :
      const prototypeFoo = { foo: foo };
      const prototypeBar = { bar: bar };
      Object.setPrototypeOf(myObject, { ...prototypeFoo, ...prototypeBar });
      // Warning: This method do not go well with the use of the instanceof operator.

    • @lilyscarlet2584
      @lilyscarlet2584 ปีที่แล้ว

      if only the interpreter knew about function inlining...and if only there wasnt a hierarchy of object instances that were created every time you wanna do a simple thing...the real problem is that the web is not very well designed for how we use it today and javascript isnt a good language to begin with. there is nothing maintainable or good about forcing object instantiation lets just be honest and not defend oop. javascript was an unhappy accident we are coping with and frontend web has way too many layers and language transpilation and it would be better if we could somehow standardized web assembly and replace the DOM with something more sane for a dynamic web app. and we also should change our mindset about how we write code in general when it comes to web having all these messy callbacks is not a very good system. not to mention alot of companies are like 85% bloated and there are way too many people which increases the communication barrier and thats the only real justification for writing code like we do which ends up overly abstracted to the point where its hard to understand whats going on or how much memory things are using and debugging etc. and to be frank almost nobody in web is doing actual programming. and unfortunately all of the bad flaws of the web are bleeding into other areas as well and software is degrading as a result. this is probably a better alternative but again when you are dealing with constructors and objects its hard to write code that doesnt bloat out in an intuitive way and it even encourages code that is less efficient which is another fundamental flaw in web and in javascript. i guess most people are just used to this and think its normal to code this way but to me it looks like a mountain with a toothpick as its only foundation and one wrong move and the whole thing crashes down and destroys entire towns. thats how i think of web infrastructure or like a jenga game where you pull the wrong piece and the whole thing just implodes on itself. or even worse javascript allows buggy code to work and alot of things never get fixed as a result. i guess thats why you have transpiled languages like typescript but that just makes javascript an assembly target and its not a very good one at that. it just seems like everything is a cope for the fact that web infrastructure is an arbitrary thing that came to be from history and wasnt designed to work the way we use it today so we add a bunch of bandaid hot fixes and now you have all this needless complexity as a result. im curious what people think of this do you agree do you think we could do better or do you have the mindset of well it works so dont fix what isnt broken. its more of a philosophical question than anything. im on the side of i wish we could do better and i wish more people were like minded instead of going forward with how it is. but im open to hear more insight.

    • @lilyscarlet2584
      @lilyscarlet2584 ปีที่แล้ว

      @Dragon my point is that most of that complexity shouldnt be there you shouldnt need libraries to get around how bad js really is. the issue is that the web isnt designed to be used like it is it wasnt designed well to begin with. new technologies keep popping up all the time all of which are low quality. nodejs included. the excuse that apps are getting bigger doesnt justify its problems. most apps are much bigger than they should be requiring a much bigger stack than what should be necessary to run. wasm may help but time will tell.

    • @zaza-ik5ws
      @zaza-ik5ws ปีที่แล้ว

      @@lilyscarlet2584 Which is the best programming language in your opinion?

  • @ehsankhorasani_
    @ehsankhorasani_ 3 ปีที่แล้ว +12

    with utmost respect that I have to you.
    The things that your doing as Composition is 100% percent wrong.
    it's more like multiple inheritance or multiple concatenation than Composition.
    this is the most misunderstood concept in Javascript Community.
    I recommend you to take a look to the "Design patterns" book

    • @thescottyjam8906
      @thescottyjam8906 2 ปีที่แล้ว +1

      Yeah... I've been surprised at how many times I've seen this solution come up in blogs and videos among JavaScript programmers, and it's described as "composition". This pattern still carries all of the same problems that multiple inheritance carries, we've just found a way to do it without the class syntax or JavaScript's built-in prototype system.
      Wikipedia actually categorizes this pattern as a "concatenative prototyping", which, *gasp*, weren't we just trying to avoid prototypes? en.wikipedia.org/wiki/Prototype-based_programming#Concatenation

    • @harkitnebamake
      @harkitnebamake 2 ปีที่แล้ว

      I guess he is a lil wrong in using the principle of composition in this particular implementation.
      I feel it is more like multiple inheritance in the way that , the implementation of fly and swim has already been created.
      And every object created in the shown way gets the same implementation.
      Can you be more elaborate ?
      I am curios as to how this is wrong.

    • @thescottyjam8906
      @thescottyjam8906 2 ปีที่แล้ว

      @@harkitnebamake Like you said, what he's doing more closely follows the idea of multiple inheritance. Composition is really much simpler, you do it all the time, maybe without realizing you do it. All composition is, is taking one object and sticking it on a property of another object. The phrase "favor composition over inheritance" means if you want to share behavior, instead of inheriting from a base class, make a class with your common functionality and have other classes utilize it. If you search for the phrase "composition over inheritance", and look for results in any language but JavaScript, you're sure to find a number of good examples and tutorials explaining it.

  • @neverchesterfield
    @neverchesterfield 3 ปีที่แล้ว +46

    Incredible feeling when I finally understood why you'd need composition: "what if you wanted a monster that can swim and fly" and, as someones who *hates* copy-pasting code it actually struck me. Thanks !!

    • @paxer2k
      @paxer2k 2 ปีที่แล้ว +6

      Design patterns? Interfaces? Abstract classes/methods? C++ can even use multiple inheritance. Furthermore, within JS, you can just apply the principles of interfaces and it will tackle the issue just fine.

    • @neverchesterfield
      @neverchesterfield 2 ปีที่แล้ว +1

      @@paxer2k Did you mean to answer my comment?

    • @ipodtouch470
      @ipodtouch470 2 ปีที่แล้ว +8

      @@paxer2k multiple inheritance can be messy though especially if you run into the diamond problem.

    • @GameFuMaster
      @GameFuMaster ปีที่แล้ว +6

      @@paxer2k Except inheritance is flawed because it requires foreknowlege.
      When you look at it, swimming and flying are basically the same thing, except they're through different mediums (liquid vs gas). They both move in X, Y, Z directions. When you use inheritance, you're stuck with your initial presumptions. With composition, the input matters much less, and you just need to worry about your outputs being correct.

    • @harleyspeedthrust4013
      @harleyspeedthrust4013 ปีที่แล้ว +6

      @@paxer2k interfaces do solve the problem - at the end of the day you shouldn't be using JS if you're building serious software. the problem with interfaces and classes is that they are poor models of real data structures. code changes, and inheritance hierarchies are a bitch to change. it's also very easy to go crazy and overuse inheritance, especially in a language like java where everything has to be in a class even if it doesn't make sense. as i mentioned before, the biggest problem with inheritance is that it rarely models data structures and relationships well, so you end up fitting the problem to the code when you should be fitting the code to the problem. "use the right tool for the job;" inheritance is almost always the wrong tool.

  • @rajeevsinxh
    @rajeevsinxh 4 ปีที่แล้ว +31

    when he said "the ability to create a new type of monster is really powerful" I cracked lol

  • @mrfreddie04p
    @mrfreddie04p 2 ปีที่แล้ว +11

    I have a small problem with this solution. swimmer() and flyer() functions appear to get access to the "name" value via closure. So, if I update the name property after creation the object, it would not be reflected in swim() and fly() functions. They would still output the original name.

    • @porobertdev
      @porobertdev 7 หลายเดือนก่อน

      You need to use the `this` keyword which tells what context to use.
      The context of a method is the object owning that method. But the type of methods used here are arrow functions. An arrow function doesn't have a context on its own, but it "inherits" or uses the context of the outer function.
      Since the outer function is a regular function, the context (`this`) is the global object: `window`.
      Thus, we need to switch from arrow function to a regular function (method).
      function swimmer(name) {
      return {
      name, // "shorthand" for name: name
      swim() {
      console.log(`${this.name}: sweam`);
      console.log(this); // object created
      }
      }
      }
      let monster = swimmer('Robert'); // monster = { name: 'Robert', swim: ... }
      monster.swim();
      // "Robert: sweam"
      // this = monster object
      A great article on the `this` keyword is this one: dmitripavlutin.com/gentle-explanation-of-this-in-javascript/

  • @soniablanche5672
    @soniablanche5672 4 ปีที่แล้ว +73

    Plot twist: Inheritance in javascript is actually composition under the hood.

    • @olezhonnv3215
      @olezhonnv3215 ปีที่แล้ว +3

      @MUSICAL INFLUENCE You can do
      class two extends three
      class one extends two
      But there is no multiple inheritance in js. You cant write
      class one extends two, three

    • @bayrock1337
      @bayrock1337 ปีที่แล้ว +1

      Even more reason not to use it.

  • @emibademi1
    @emibademi1 3 ปีที่แล้ว +18

    What about memory efficiency for example: What if we have tons of monsters? All the monster methods will be copied in every monster that we created without using prototypal inheritance.

    • @SurenEnfiajyan
      @SurenEnfiajyan 2 ปีที่แล้ว

      Good point. But from the other hand with prototypical inheritance the property access time increases.

    • @jonteguy
      @jonteguy ปีที่แล้ว +6

      @@SurenEnfiajyan Polymorphism is inheritence by nature. This guy is attempting to make it sound like it's composition, what a tool he is, he should not be educating people to the extent he is attempting to in this video.
      Is inheritence being misused? For sure. But people misuse it because it is a simple way of coming up with a solution, you can use inheritence very effecitely if you just understand what real good design is. I use both composition and inheritence, as you should because not all tools are made for the same problems.

  • @CaamSerenity
    @CaamSerenity 4 ปีที่แล้ว +70

    Wait until he learns about TypeScript and how to use interfaces properly. Alternatively, to achieve the exact same result but way more readable, Mixins.

    • @thedankest1974
      @thedankest1974 4 ปีที่แล้ว +2

      Well said.

    • @yackawaytube
      @yackawaytube 4 ปีที่แล้ว +1

      I find AOP using decorators to be superior approach to address cross cutting concerns than mixins

    • @CaamSerenity
      @CaamSerenity 4 ปีที่แล้ว +1

      @@yackawaytube Depends on what you want to do. The problem with decorators is that they are not allowed to add properties to a class in a typesafe way. Mixins can do that. I personally prefer decorators as well, but sometimes they are not the right tool for the job. Though, often they are. In this example they'd not be as great.

  • @arifwahyudiansyah2809
    @arifwahyudiansyah2809 3 ปีที่แล้ว +13

    Because inheritance is so important in object-oriented programming, it is often highly emphasized, and the new programmer can get the idea that inheritance should be used everywhere. This can result in awkward and overly complicated designs. Instead, you should first look to composition when creating new classes, since it is simpler and more flexible. If you take this approach, your designs will be cleaner. Once you’ve had some experience, it will be reasonably obvious when you need inheritance. (Bruce Eckel)

    • @harleyspeedthrust4013
      @harleyspeedthrust4013 ปีที่แล้ว +4

      agreed. inheritance is almost always the wrong tool for the job, but when it fits, it fits well. that's rare though and new programmers should be taught to fit the code to the problem rather than fit the problem to the code. it's a sad mistake that java is taught in so many schools around the US as a first programming language, but then again this is the same country with a high school physics curriculum that has been stripped of calculus. it's ironic that isaac newton invented calculus to describe physics and some big wigs in suits decided he was wrong

    • @jonteguy
      @jonteguy ปีที่แล้ว

      ^This, it is so annoying to see people talk bad about inheritence when they simply do not know how to use the tool effectively.
      Also he is talking about polymorphism but he doesn't mention that, polymorphism is inheritence. The guy who made it is a tool.

  • @jaysonkmendoza
    @jaysonkmendoza ปีที่แล้ว +3

    Well I think this is more mistaking the use case for polymorphism in OOP. Polymorphism is best used when a bunch of classes have the same set of behaviours but execute them differently. It’s not very useful when your child classes are too different than the base class or when the available behaviours are changing over time.
    If you have behaviours that could change over time then other patterns like the strategy pattern (similar to you used in your example) to hold the algorithm or even data structures of them with the class being sent an action or event that it acts on using the correct strategy.

  • @stephenhowe4107
    @stephenhowe4107 ปีที่แล้ว +1

    @3:26: Yes interesting example. But that is because your language does not have multiple inheritance (unlike C++).
    If it did, you could have these behaviours as mixin's and you would inherit from as many mixins that give the behaviour required.
    But I am not sure I would go down this road.
    Then in C++, you have protected and private Inheritance and also virtual inheritance.
    And only public inheritance gives you type substitutability as per Barbara Liskov's paper.
    But all of this, is basically modelling and comparing what your language provides with the ability to model your situation in the elements your language provides.
    And as you say, Composition helps
    In C++ we have
    Multiple Inheritance
    Virtual Inheritance
    Public, protected private inheritance of data and functions.
    Virtual functions.
    Pure Virtual functions.
    Function Overloading
    Function Overriding
    Function Pointers
    All of this provides a rich set of choices on trying to model situations. Other languages have less and therefore the modelling is harder.

  • @masoodahmed4718
    @masoodahmed4718 4 ปีที่แล้ว +4

    Wait till people trying to justify OOP in comments section discover how OOP and inheritance chains with overly excessive use of patterns in enterprises actually make the code more hard to understand and make the maintainers life a nightmare. That is when you realize using three functions for composition instead of 2 interfaces & 4 classes was a better idea
    EDIT: Above lessons learned from java experience & never wana go back.

    • @skaruts
      @skaruts 4 ปีที่แล้ว +4

      Both inheritance and composition are OOP concepts. Not to be confused with procedural programming or ECS (although in the video he is kind of leaning toward procedural programming, because js allows that). _"Composition over inheritance",_ or *_"has a--,_*_ instead of _*_is a--",_* is a very old advice on how to do OOP. The problem is tutorials online have always been overrun by inheritance, despite that. Probably because in fully OO languages (e.g., Java), composition can be a bit unwieldy (Bob Nystrom has a nice talk about it from that perspective (in Dart): th-cam.com/video/JxI3Eu5DPwE/w-d-xo.html ).

    • @masoodahmed4718
      @masoodahmed4718 4 ปีที่แล้ว

      @@skaruts you are thinking of a different kind of composition, I meant function composition which is different from composition concept found in OOP.
      Oh I am a big fan of bob nystrom and his articles on languages and compilers.

    • @thecolorblue7427
      @thecolorblue7427 2 ปีที่แล้ว +3

      @@skaruts thank you for that video, I have no idea why, but it had literally the exact problem i was coming across, with the same exact situation. Lol, it was really perfect, thanks again

  • @olezhonnv3215
    @olezhonnv3215 ปีที่แล้ว +1

    JS does not have interfaces. Example about monsters is not correct.
    Inheritance problem is not described in this example.
    Composition can be done in OOP, but this example doesnt cover that.

  • @eymeen
    @eymeen 3 ปีที่แล้ว +1

    what if
    monsterAddProperty('fly','eagle');
    isn't this better

  • @brokula1312
    @brokula1312 2 ปีที่แล้ว +1

    Better example would be:
    f(g(h(x)));
    or:
    flyer(walker(swimmer(monster)));
    or
    compose(walker, swimmer, flyer)(monster);

  • @softwarelivre2389
    @softwarelivre2389 4 ปีที่แล้ว +5

    But then you are not getting the benefit of propotypal inheritance. Therefore, if you had lots of similar objects, they would probably cause a big impact on performance.

  • @kevinrobertandrews
    @kevinrobertandrews 4 ปีที่แล้ว +48

    I love that you can talk about high level concepts while still writing real code. Amazing, and subbed!

  • @user-cy3kn7zx1l
    @user-cy3kn7zx1l 3 ปีที่แล้ว +6

    Is there a reason for wrapping those methods in an object to then be returned from a function rather than referring to those functions in the creator return object itself?

    • @harkitnebamake
      @harkitnebamake 2 ปีที่แล้ว +1

      GOod ques.
      I guess in this case , it saves implementing the fly and swim functionality again and again and commonly implementing them just once.
      In real world you'd make an interface Flyable and implement that interface everytime and Use the principle of composition while creating objects.
      That way you'd provide specific implementation to your concrete classes . Everytime.

  • @sudarshankj
    @sudarshankj 3 ปีที่แล้ว +1

    To all those comments which are pro-inheritance, this video took an example to display why inheritance might be bad by giving an example. Even one scenario disproving 'Inheritance is the best' clearly indicates that we cannot be binary in our choices, but we ought to be analogous by considering various factors before choosing a strategy.

  • @hcr2bangladesh
    @hcr2bangladesh ปีที่แล้ว +1

    i like how beautifully you read the script from the other side , lol

  • @xKhfan213x
    @xKhfan213x 2 ปีที่แล้ว +8

    I'm a little late seeing this but the comparison of these ideas along with the examples you gave is a pretty good example of the differences between object oriented programming and functional programming.
    With inheritance, you are following the oop paradigms. Everything is an object extending the capabilities of other objects.
    Composition on the other hand has you break your objects into separate functions. You can then just take which functionality you want to inherit by adding the function to the object your creating. Think of this like a Lego set. The functions you create are your Lego pieces. To create an object you just piece together your Lego pieces.
    Which is better is a verry debatable topic, both having their pros and cons. Just remember what one can do, the other can as well and it's typically best to follow either oop or functional programing practices and not mix them in the same project. It can be confusing for other developers, especially if they aren't familiar with functional programming

    • @stephenhowe4107
      @stephenhowe4107 ปีที่แล้ว +1

      Yes but there are situations where inheritance is a good choice and others where it is a poor choice. This clip gives food for thought and at the same time reveals language limitations to your ability to model the situation.

    • @jonteguy
      @jonteguy ปีที่แล้ว

      This is not true, polymorphism itself is inheritence and that is what he is talking about.
      He has no freakin' idea what he's talking about in this video. Look up polymorphism if you are not sure what I'm talking about.
      It's a joke. Also oop can be just as fast and neat as functional programming, people are simply misusing it tremendously because they don't know better, it is simply a simple way of doing things.
      Also, again: polymorphism is inheritence but it is also functional programming.
      This guy is a tool, he should not be educating people to the extent he is attempting to.

  • @kimpadova262
    @kimpadova262 ปีที่แล้ว +1

    Bro, I love your channel, but do I ever blink??

  • @treyquattro
    @treyquattro ปีที่แล้ว +1

    Kyle, what sort of nightmare location do you live in where sharks can walk?!

    • @flipflap4673
      @flipflap4673 ปีที่แล้ว

      Not to speak of the Monsters in general ...

  • @knightmarerip711
    @knightmarerip711 2 ปีที่แล้ว +8

    This just blew my mind away! For a few months now, I have been looking for a way to write better classes. Rather than having all my functions defined in a class, which makes it bigger that it should be, I wanted to define classes outside and just reference them when I construct my class. This is really awesome! Thanx for sharing!!!

    • @pagatelabirra
      @pagatelabirra ปีที่แล้ว +2

      With new object prototype methods you can return Object.assign(monster, swimmer(monster))

  • @Gol_D_Roger_The_Pirate_King
    @Gol_D_Roger_The_Pirate_King 4 ปีที่แล้ว +5

    So basically you are telling me to create a factory function.

  • @ben790924
    @ben790924 4 ปีที่แล้ว +1

    Why you spread monster inside flying...creator function

    • @ohmegatech666
      @ohmegatech666 ปีที่แล้ว

      I was wondering the same thing. It seems like this takes all the properties from monster and puts it in the output object. Right now his monster object only has one property name but you could add more

  • @jacobpolicano7289
    @jacobpolicano7289 2 ปีที่แล้ว +5

    Does this have a negative impact on memory and should we consider that when deciding between composition and inheritance? I notice we are recreating these functions every time we create our new Monster, but with the class-based approach we're actually referencing a single object that houses our related functionality.

    • @coder_one
      @coder_one 2 ปีที่แล้ว +3

      Great question! Without using prototypes, whenewer we create new object we repeated all these methods, without using the prototype chaining. This probably causes a lot of memory loss

    • @ikemkrueger
      @ikemkrueger 2 ปีที่แล้ว

      @@coder_one Memory is cheap today.

    • @CottidaeSEA
      @CottidaeSEA 2 ปีที่แล้ว

      @@ikemkrueger Google Chrome..? :)

  • @wwijsman
    @wwijsman 4 ปีที่แล้ว +3

    This solves the same problem as multiple inheritence. Python supports multiple inheritence, but I'm not sure if Javascript does.

  • @ox6542
    @ox6542 8 วันที่ผ่านมา

    This can only be applied to functional language like javascript right? For language which requires classes to be strictly defined (e.g. Java) seems cannot use this trick😅

  • @RayParker
    @RayParker 4 ปีที่แล้ว +12

    The problem with your premise is that all of the actions should have been declared and the Monster level and then the specific monster classes respond in the positive to their specific actions. For example, when you ask a monster to swim he might just sink or something, but a Shark swims like crazy.

    • @razbuchnik6007
      @razbuchnik6007 2 ปีที่แล้ว

      You may define types of swimming. bird.swim and fish.swim are two different methods. You may apply each of them respectively. Like so:
      const bird = { swim() { } } // may only just sink, must go up after 10 seconds, cannot go too deep
      const fish = { swim() {} } // different entirely from bird swim - can do just whatever he wants in the water
      function sharkMaker() { return { swim: fish.swim } }
      and
      function birdMaker () { return { swim: bird.swim } }
      Which are two different things

  • @DevMeloy
    @DevMeloy ปีที่แล้ว +1

    There is always a few ways to perform the same task, I prefer OOP over a functional programming, and I get the "problem" Kyle is trying to show, properly architected classes wouldn't run into these issues. The biggest issue is that JS is a prototype language with syntactical sugar for classes, moving to a true OO language gives more options to handle different situations.

  • @olivermeissner5198
    @olivermeissner5198 4 ปีที่แล้ว +8

    ends up in implementing a special swinning-method for a shark and another special swimming-method for a penguin... in the end this way of coding seems to be completely useless.

  • @kartikmaurya9386
    @kartikmaurya9386 11 หลายเดือนก่อน

    Will this also be considered functional composition, advantage is that I can add any power to the monster by addPower method:
    function monster(name){
    const monsterPack = {
    name,
    addPower: fn => {
    monsterPack[fn.name] = () => fn(name);
    return monsterPack
    }
    }
    return monsterPack;
    }
    const bite = (name) => `${name} can bite`
    const fly = (name) => `${name} can fly`
    const monsterThatCanFly = (name) => monster(name).addPower(fly);
    const monsterThatCanFlyAndBite = (name) => monsterThatCanFly(name).addPower(bite);
    const pterodactyl = monsterThatCanFlyAndBite('ptero');
    console.log(pterodactyl.fly())
    console.log(pterodactyl.bite())

  • @DigitalAlchemyst
    @DigitalAlchemyst 7 วันที่ผ่านมา

    LOL. I was looking for a little clarification on the concept in general. I had a coding challenge this morning the goal was to make a player character and to give it abilities by composition. This video pretty much solves my coding challenge lol. Let me know when you are ready Kyle and my character will come slay your monsters ;P

  • @nicer00ster78
    @nicer00ster78 4 ปีที่แล้ว +7

    You never really explain WHY it's better or WHY we shouldn't use inheritance. You're just showing us how to convert the inheritance concept into composition (which is fine) but if your videos title is "Why you should stop using inheritance" I would like to know why you're making that claim. :D

    • @firedforfighting
      @firedforfighting 4 ปีที่แล้ว +3

      @3:08 I understood the 'why' as a way to avoid duplicating logic by using composition

    • @aammssaamm
      @aammssaamm 4 ปีที่แล้ว

      Cause he does not quite understand what he is talking about. He just repeats the wrong approach he adopted from other people and never bothered to question it.

    • @Marko_Djuricic
      @Marko_Djuricic 4 ปีที่แล้ว

      "Shar walked" is a great example why..

    • @aammssaamm
      @aammssaamm 4 ปีที่แล้ว

      ​@@Marko_Djuricic "walk" is not a class, it's just a type of movement which is much broader term and which can be a class. Most of the people have issues with generalization and abstraction. "Walk" can be a property value only in this case.

    • @Marko_Djuricic
      @Marko_Djuricic 4 ปีที่แล้ว

      @@aammssaamm who said it was a class? I said that sharks don't walk but because of inheritance in this case, they do.. that's the problem with inheritance.. you can't change the parent class without effecting it's children aswell..

  • @frozen_tortus
    @frozen_tortus 3 ปีที่แล้ว +1

    Unfortunately, you just demonstrated a concept called 'multiple inheritances', I guess we can thank MPJ who I asked multiple times to remove that video teaching the internet what Composition is.
    Here is false video in question: th-cam.com/video/wfMtDGfHWpA/w-d-xo.html
    Short answer: Composition is containment, inheritance is mixing.
    Your code still suffers from the fragile base problem typically associated with inheritance.
    Following is the quote from user MoTTs_ from Reddit who I learn this from:
    old.reddit.com/r/learnjavascript/comments/gxw7yl/understanding_composition_in_place_of_inheritance/ft61d3l/
    Inheritance is always some process of mixing/including/concatenating the guts of one type into another type, even if we do that task manually rather than having the language do it for us, even if we don't affix it with a sticker that reads "inheritance".
    Composition, on the other hand, is about one type containing another fully encapsulated type. If we wanted to do composition, then our own object would need to be written like this:... (more on the link)
    Please consider updating your video

  • @BW022
    @BW022 ปีที่แล้ว

    I understand the thinking, but the example wasn't great. The fact the object allowed a shark to walk already shows that movement is not something common between monsters and thus should be handled differently. If sharks can walk, then the caller must know not to call Shark.Walk(). If so, why can't you add Fly() and Swim() to the base monster class and rely on people not calling Ape.Fly() or Eagle.Swim()? If you must avoid this, you need a better movement system. Why not implement CanMove(movementType) function and Move(movementType) functions passing in the movement type? Rather than Eagle.Fly() why not Eagle.Move(mt_fly)? Then setup Monster to pass in it's movement types Monster.Create({mt_walk,mt_swim,mt_fly}). Both methods solve this.
    Yes, classes and objects are often overkill in JS. Yes, this is an alternate approach. Only, it has its own issues as the code gets longer and longer and there were far easier approaches to avoiding the issue by thinking about it in the first place. I know it's hard to come up with easy examples to demonstrate concepts, but honestly this one was trivial to simply implement movement in the object knowing that multiple movements might be possible.

  • @dreamfly555
    @dreamfly555 4 ปีที่แล้ว

    Never seen a Shark walked. Does that violate the L in SOLID? AttackerAndWalker()? Does that violate the S in SOLID? Are you preaching not using object-oriented programming? Like this: th-cam.com/video/QM1iUe6IofM/w-d-xo.html
    If so, good for you.

  • @stephenc6955
    @stephenc6955 ปีที่แล้ว

    "Inheritance Sucks" ? Really ? Coming from a trust fund kid ? OUTRAGEOUS !

  • @FilipCodes
    @FilipCodes ปีที่แล้ว

    Inheritance bad... proceeds to implement even worse thing. I guess decorator pattern was too complicated

  • @lifebarier
    @lifebarier 2 ปีที่แล้ว

    Your oop example rubs me really wrong way. Your flying+swiming monster would not pass instanceof swimingMonster or instanceof flyingMonster. Bad architecture, such properties are bit more advanced than to be just handled by inheritance. There are entity something somethings to handle such things.

  • @undergroundo
    @undergroundo ปีที่แล้ว

    TL;DR: "Nailing a nail to the wall using a screwdriver takes forever and can hurt your hand. Therefor, get rid of all your screwdrivers, and use a hammer for everything".

  • @meowcat64
    @meowcat64 2 ปีที่แล้ว

    I think you used a bad example to explain why Inheritance is something that should never be used. No skilled developer who understands how to code with inheritance would write SwimmingMonster and FlyingMonster as different parent classes for the exact reason you stated... instead you'd create a single Monster parent that has functionality for both walking and swimming, and you would easily toggle the walking or flying functionality in child classes that extend Monster by using a boolean or enum.
    The functionality for swimming and flying could still be split up in the Monster class in separate component classes. And now you have the best of both worlds, and can easily write some code to support the flying and swimming component in classes that aren't Monster if necessary (or put it in a more general Agent parent class that handles all possible components an Agent can have and still reaps the benefits of inheritance)
    Of course this is entirely preference, which is why I disagree with the general sentiment that people should stop using inheritance. Its very valuable when used correctly, but you do highlight a very easy pitfall that users can fall into if they are unskilled and create a bad program architecture when using inheritance.
    Mostly speaking from my experience writhing a large RPG game in Java. I primarily follow OOP and combine other practices like Composition whenever its beneficial, and I have no complaints about inheritance. I do however constantly see convoluted troubleshooting posts from many other devs using the same engine as me except with an ECS that relies solely on Composition, and while I see many of the benefits, I also am not jealous of all the extra troubleshooting issues they run into as a result of being limited strictly to using an ECS for absolutely everything.

  • @fasic46
    @fasic46 2 ปีที่แล้ว

    And me as python developer watching this like: whaaaaaaaaaaaaaaaaaaaaaat, i see the point, but not the problem. lucky i know JS, Java, C# so yea...everything except python sucks :D

  • @petterileino4327
    @petterileino4327 3 ปีที่แล้ว

    Shark walked... Shark attacked... Some serious Bloodborne flashbacks. Help me god.

  • @RazBuchnik
    @RazBuchnik 9 หลายเดือนก่อน

    Can I use composition as you described but with classes rather then functions? It's a little confusing - should I choose classes at all? Since functions can be a blueprint that creating objects the same way as classes, and also cam implement the composition we so desire, but currently today, classes cannot. What do you think?

  • @programadordelassombras
    @programadordelassombras 3 หลายเดือนก่อน

    if you needed to track the state of your monster, like hp, health etc., would, you still use this concept, or strictly classes? I am sure there is no one size fits all approach, so I would assume the solution might be a hybrid of both?

  • @olezhonnv3215
    @olezhonnv3215 ปีที่แล้ว +3

    It depends on usecase, sometimes inheritance is good, sometimes composition.

  • @kavyashreebj5848
    @kavyashreebj5848 ปีที่แล้ว

    Could have taken tortoise or frog as an example for a swimming monster.. Kinda hard to imagine a walking shark 🤔
    Okay i am procrastinating. Let me continue watching the video lol

  • @sawilliams
    @sawilliams 2 ปีที่แล้ว

    to bad you just can't extend multiple classes:
    class ChildClass extends ParentClass, OtherParentClass {
    ...
    }

  • @TheDiggidee
    @TheDiggidee ปีที่แล้ว

    You're taking an OOP paradigm (one of the pillars of OOP as well) and tying to apply it to Javascript which is a functional language.

  • @wongkinchung9985
    @wongkinchung9985 ปีที่แล้ว

    It doesn't mean inheritance is bad, but just JS does not support multiple inheritance. Using a factory pattern without any classes ruins the auto-completion in IDE and requires more human memory to use them

  • @bxlbjorn
    @bxlbjorn ปีที่แล้ว

    I'm going to have to rewire my brain from classes... Is there a way to combine? Classes for simple properties and composition for functionalities?

  • @rene7952
    @rene7952 3 ปีที่แล้ว

    Mhhh, i don´t really understand. I can create a class with all methods for swim, fly, attck, walk etc. I create an instance of this class for a flying swimming monster. Why is Composition a better way?

  • @marcodev3375
    @marcodev3375 ปีที่แล้ว

    I prefer making compositions using esm module way, by using import, export, re-export.

  • @IndellableHatesHandles
    @IndellableHatesHandles ปีที่แล้ว

    This is basically just creating a solution for a problem that was invented by the language you're using.

  • @paemox
    @paemox 2 ปีที่แล้ว +1

    Horrible advice, if FlyingMonster heavy depends on Monster class and extends it, you will have envy class.

  • @GammaSouljah
    @GammaSouljah ปีที่แล้ว

    At the end you said its not object-oriented... Well it still is. you just added behaviour to an object differently using composition and not inheritance. But at the end of the day, you still have a complex instance that represents an object of unique data that can be passed around and used.

  • @wahoobeans
    @wahoobeans ปีที่แล้ว

    Es6: we want classes!
    Afterwards: actually, just kidding. Classes suck.

  • @theBigBugGuy
    @theBigBugGuy 10 หลายเดือนก่อน

    Can we implement this using function borrowing, call, apply or bind?

  • @1flybyguy
    @1flybyguy 4 ปีที่แล้ว +4

    The wardrobe changes are messing with my mind. You still have a soothing voice, so I'm good.

  • @kennethgee2004
    @kennethgee2004 ปีที่แล้ว

    No inheritance works great. You just have to know how to use it. For instance interfaces and making implementations.

  • @ankk98
    @ankk98 9 หลายเดือนก่อน

    While the concept of composition is good, JS looks like a half-baked language.

  • @thomasandolf7365
    @thomasandolf7365 ปีที่แล้ว

    and... you now have no type safty and the function returns obj, which means we can explode at any time.

  • @vukkulvar9769
    @vukkulvar9769 ปีที่แล้ว

    There are legitimate reasons to use inheritance.
    Like a standard made years ago by morons that is the essential foundation in your company business field accross the world.

  • @sebastianbehrens4492
    @sebastianbehrens4492 3 ปีที่แล้ว +3

    Or, like in about every other language with inheritence and interfaces, you could use a combination of generic and abstract methods and add concrete methods with interfaces.

    • @justsomeguy8385
      @justsomeguy8385 2 ปีที่แล้ว

      Why would you even bring that up when we are talking about JavaScript? Unless you mean he should be using TypeScript, which is hard to disagree with.

  • @codingchannels4103
    @codingchannels4103 4 ปีที่แล้ว +4

    please provide final code file in the description for us to easily look up the code

  • @Learnbynet
    @Learnbynet 3 ปีที่แล้ว

    scammer, pause at 7:24 , you get no type for `.fly()` !

  • @Abdallah_Ismail
    @Abdallah_Ismail ปีที่แล้ว

    Who's here in the comment trying to figure out what kind of a monster that could fly and swim at the same time :D

  • @pgoeds7420
    @pgoeds7420 4 ปีที่แล้ว +2

    Is your version of a shark supposed to walk? Did a pop show convince you 50% of sharks dance?

  • @sircalist
    @sircalist ปีที่แล้ว

    Still waiting for a video titled "Composition Vs Inheritance - Why You Should Learn When To Use One Or The Other"

    • @cocoscacao6102
      @cocoscacao6102 ปีที่แล้ว

      Dream on. Subtle differences don't jibe well with the hype train, and content needs likes so it doesn't get spanked by the algorithm. Choo! Choo!

  • @waterp2202
    @waterp2202 3 ปีที่แล้ว

    So..., it's the same result with Object.assign..., right?

  • @kungfooman
    @kungfooman 2 ปีที่แล้ว

    > no oop
    > lets make every function return objects with methods

  • @ohmegatech666
    @ohmegatech666 ปีที่แล้ว

    6:05 I'm unclear on what the spread operator is doing here. In your video on destructuring you only mention that it's used to get the rest of some array or object, which would give you a new smaller array or object, and you can give it any name you want like "rest" or "otherStuff", but that's clearly not what you're doing here. Here you're referencing the monster object after the ... so what's happening?

    • @ohmegatech666
      @ohmegatech666 ปีที่แล้ว

      OK I looked it up and the reason for my confusion is that the ... operator actually can do 2 totally different (and sort of opposite) things.
      1. It can be the "rest" operator which gets you the rest of an array or object like this
      [a, b, c, rest...] = alphabet
      This will give you two variables a, and b which are just single letters, then rest which is a new array that's smaller
      2. it can be the "spread" operator which unpacks a full array or object into separate things which is what he's doing here. This will get you a bunch of separate things rather than an array or object. In this case, it's breaking down the monster from an object into just properties (well, one property), and its breaking down the object that gets returned from the swimmer function into just a property which is the function that actually prints name is swimming

  • @Omar-gr7km
    @Omar-gr7km 3 ปีที่แล้ว +1

    I like your videos. This one misses the mark though.
    Best to stick with tried and true design patterns for what you're presenting.
    You're (probably purposefully) using inheritance wrong. Decorator pattern or mixins will cleanly do what this video aims to do. Also, that's not really composition.

  • @brunoemre
    @brunoemre 7 หลายเดือนก่อน

    why not just console log inside swim and fly directly

  • @goldfishbrainjohn2462
    @goldfishbrainjohn2462 2 ปีที่แล้ว

    Inheritance makes tracing code much harder when there are more than one level of inheritance.
    I hate that.

  • @mauro1518
    @mauro1518 2 ปีที่แล้ว

    i don't get it... why did you used - return { swim: () ....}?

  • @DIGGERfromAR
    @DIGGERfromAR ปีที่แล้ว

    ES6 classes are antithetical to the prototypical language.

  • @ahmedboutaraa8771
    @ahmedboutaraa8771 4 ปีที่แล้ว +3

    I always thought that brad tarversy is the one but after Watching your tutorials I think you kinda standout

    • @voidmind
      @voidmind 4 ปีที่แล้ว

      Both are really good.

  • @TarekFaham
    @TarekFaham 3 ปีที่แล้ว

    This method is so confusing.... Better to go to typescript.

  • @romarpatindol9840
    @romarpatindol9840 2 ปีที่แล้ว +2

    For how many years of just copy-pasting codes now I understand, I am amazed at the principles and the art behind the logic and you've nailed it by explaining it well, very straight to the point. Thank you man!

  • @greggreenhaw
    @greggreenhaw ปีที่แล้ว

    Seems easier to just copy the prototype of the classes u want to inherit

  • @avirupduttagupta
    @avirupduttagupta ปีที่แล้ว

    Could you please explain why we need to return ...monster instead of monster? Thank you!

    • @asagiai4965
      @asagiai4965 ปีที่แล้ว

      to return the properties, functions of monster

  • @AndrewErwin73
    @AndrewErwin73 4 ปีที่แล้ว +9

    You are describing interfaces and overloading/overriding (polymorphism) that are available in actual OOP languages. Javascript really isn't designed (fundamentally) as an object oriented language.

    • @jochenpanjaer980
      @jochenpanjaer980 4 ปีที่แล้ว +1

      Correct, even with ES6 (and higher), it is missing a lot of the OOP (and SOLID) principles.

    • @DEVDerr
      @DEVDerr 4 ปีที่แล้ว +2

      @@jochenpanjaer980 That's why TypeScript comes in :)

    • @jochenpanjaer980
      @jochenpanjaer980 4 ปีที่แล้ว +2

      True, but I do like the loosely typed nature of javascript.
      I just code in es2015 and transpile everything afterwards.

    • @DEVDerr
      @DEVDerr 4 ปีที่แล้ว

      @@jochenpanjaer980 How loosely typed nature can be enjoyable? XD It always pisses me off every goddamn time

    • @jochenpanjaer980
      @jochenpanjaer980 4 ปีที่แล้ว +1

      @@DEVDerr I love it, especially when you are working with unknown data. Eg, you can tune mongoose queries on the fly because the $match and $group objects are json objects. Or add custom flags and functions to existing components (eg authorization tokens).

  • @theengineer6848
    @theengineer6848 4 ปีที่แล้ว +1

    Inheritance shouldn't be used with the purpose of reusing existing implementation code. Its purpose is to handle all similar objects in a similar way. Check Liskov substitutability principle. It basically becomes like interfaces. In your example, there might still be a need to handle all monster objects in a similar fashion, without knowing if it can fly/swim etc, like obj.takeAction() or something. Point is you'd need both inheritance and composition for different reasons.

    • @olezhonnv3215
      @olezhonnv3215 ปีที่แล้ว +1

      It is true for OOP languages like Java. But there are no interfaces in JS.