Why Favor Object Composition Over Class Inheritance? A Deep Dive

แชร์
ฝัง
  • เผยแพร่เมื่อ 26 ก.ค. 2024
  • Are you a programmer trying to understand the difference between object composition and class inheritance? In this video, We'll take a deep dive into why you should favor object composition over class inheritance in your code. After explaining what object composition and class inheritance are, we will explore what object composition and class inheritance are, and explore the advantages and disadvantages of each. You'll learn about the composition vs inheritance debate and why composition is often the better choice for achieving code reuse. We'll also take a look at the benefits of using composition over inheritance, and why it's important to understand this concept for better programming practices.⚡️❤️
    My video covers a range of topics, from functional programming to C# programming and beyond. I provide C# tutorials to help you improve your skills and stay up-to-date with the latest dotnet trends. My video is perfect for programmers looking to improve their understanding of inheritance programming and composition programming. I also cover essential programming concepts, including OOP, C#, functional programming, and .NET. With Zoran Horvat, you'll have access to the best programming tutorials, ensuring that you have the skills you need to succeed.❤️
    So, whether you're a beginner or an experienced programmer, this video will help you understand the difference between inheritance and composition and why you should favor composition over inheritance. Join me on Zoran Horvat's channel to learn more about object composition, OOP, C# programming, and functional programming. Don't forget to subscribe to my channel for more programming tutorials and tips!❤️
    ✅🔔Become a patron and get access to source code and exclusive live streams: / favor-object-but-81382143
    ✅🔔 Subscribe ► / @zoran-horvat
    ⭐ Learn more from video courses:
    Beginning Object-oriented Programming with C# ► codinghelmet.com/go/beginning...
    ⭐ Collections and Generics in C# ► codinghelmet.com/go/collectio...
    ⭐ Making Your C# Code More Object-oriented ► codinghelmet.com/go/making-yo...
    🗳 Pluralsight Courses ► codinghelmet.com/go/pluralsight
    📸 Udemy Courses ► codinghelmet.com/go/udemy
    ▬▬▬▬▬▬▬▬▬▬▬
    ⚡️ Have a look at our other Videos :
    👉 Other videos on this channel you may be interested in watching:
    Using GitHub Copilot to Write Complex Code | Step-by-step Tutorial ► • Using GitHub Copilot t...
    👉 Coding with GitHub Copilot - Beginner to Master | VS Code Demo ► • A Comprehensive Guide ...
    👉 What is Covariance and Contravariance in C# ► • What is Covariance and...
    How to Initialize a Clean ASP.NET Core Project with Entity Framework Core and Identity ► • How to Initialize a Cl...
    ⚡️Chapters:
    ▬▬▬▬▬▬▬▬▬▬▬
    ⌚ 0:00 Today's Topic: Composition vs Inheritance
    ⌚ 0:17 Why Favor Object Composition Over Class Inheritance?
    ⌚ 18:13 Outro
    ▬▬▬▬▬▬▬▬▬▬▬
    #inheritance #composition #objectorientedprogramming #inheritence #compositionoffunctions #oop #csharp #dotnet #zoranhorvat
    ▬▬▬▬▬▬▬▬▬▬▬
    ⭐ CONNECT WITH ME 📱👨
    🌐Buy me a Coffee ► ko-fi.com/zoranhorvat
    🗳 Pluralsight Courses ► codinghelmet.com/go/pluralsight
    📸 Udemy Courses ► codinghelmet.com/go/udemy
    📸 Join me on Twitter ► / zoranh75
    🌐 Read my Articles ► codinghelmet.com/articles
    📸 Join me on LinkedIn ► / zoran-horvat
    ▬▬▬▬▬▬▬▬▬▬▬
    👨 About Me 👨
    Hi, I’m Zoran, I have more than 20 years of experience as a software developer, architect, team lead, and more. I have been programming in C# since its inception in the early 2000s. Since 2017 I have started publishing professional video courses at Pluralsight and Udemy and by this point, there are over 100 hours of the highest-quality videos you can watch on those platforms. On my TH-cam channel, you can find shorter video forms focused on clarifying practical issues in coding, design, and architecture of .NET applications.❤️
    ▬▬▬▬▬▬▬▬▬▬▬
    ⚡️RIGHT NOTICE:
    The Copyright Laws of the United States recognize a “fair use” of copyrighted content. Section 107 of the U.S. Copyright Act states: “Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phono records or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright." This video and our youtube channel, in general, may contain certain copyrighted works that were not specifically authorised to be used by the copyright holder(s), but which we believe in good faith are protected by federal law and the Fair use doctrine for one or more of the reasons noted above.
    ⭐For copyright or any inquiries, please contact us at zh@codinghelmet.com
  • วิทยาศาสตร์และเทคโนโลยี

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

  • @zoran-horvat
    @zoran-horvat  ปีที่แล้ว +1

    Become a patron and get access to source code and exclusive live streams: www.patreon.com/posts/favor-object-but-81382143
    Send over the examples of your class designs that you wish me to review and, maybe, include in the future video on code redesign and refactoring.
    TH-cam is aggressively deleting all links. If you wish to submit your repo for review, use this form instead: codinghelmet.com/go/code-review-request

  • @kzelmer
    @kzelmer 5 วันที่ผ่านมา +3

    Beautifully explained. I have seen so many explanations where they use the horrible idea of "composition is a "has a" and inheritance is an "is a"".... While this is partially true, it does not completely explain why favour composition. Following that logic you could always find an "is a" relation in any hierarchy
    Love your explanation here: what problem were we trying to solve with inheritance? Movement? Ok, just have a class that represents that behaviour and use DI to use it on the "base" class. Just clear and beautiful
    Many thanks for such a simple and elegant explanation

  • @e-k4110
    @e-k4110 8 วันที่ผ่านมา +1

    Very explanatory and useful video. Thank you

  • @bogdanzarzycki9885
    @bogdanzarzycki9885 ปีที่แล้ว +10

    I'am not sure if I like the example, but the explanation is top notch. Thanks

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

      i feel the same way, i wish the example was better but good video nonetheless

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

      totalHours with sum operations. If one of MovingAbility is null, adding null to any value, will return null and not a value. Thus all ground vehicles, having flying ability as null, will always have null totalHours, correct? is it supposed to be so?

    • @DevMeloy
      @DevMeloy 2 หลายเดือนก่อน

      I agree, I'd stick with the classes. I'd have made extension methods to derive the speed from kph to anything else needed. This implementation would be fine in a small project but it appears messy and lacks focus.

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

    Hi Zoran
    Every time I learn something new, whenever you publish a new video.
    Great to see. Thanks for sharing it.

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Glad to hear it was useful!

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

    Thank you in advance, watching now but I'm sure the content will be awesome as always :)

  • @sebbefalt
    @sebbefalt 9 หลายเดือนก่อน +1

    Thanks for the simple explanation!

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

    Hey Zoran!
    I'm so grateful that you have recorded this video. I still can't quite out my finger on converting inheritance to composition.
    Could you recommend any reading on it (or one of your courses)? I might just be not fully understanding some concept of OOP that causes me to constantly try inheritance (I read a lot of books / tried creating bigger projects but still I am missing something).
    I would really appreciate your help :)

  • @anonymous.youtuber
    @anonymous.youtuber 10 หลายเดือนก่อน +1

    Beautiful video ! ❤ how you provide insight. By the way, in the context of flying vehicles there’s air speed and ground speed, making things even more complex.

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

    Amazing explanation. New sub here. Keep it up!

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

    Excellent content as always Zoran!

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +1

      Thanks! You can always take part by submitting a question about some of your designs where you need a second opinion or a guideline.

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

    Zoran is favorite TH-cam Man. Keep going, please.

  • @hauntedcrowdev
    @hauntedcrowdev 6 หลายเดือนก่อน +1

    This is a very interesting video! Very useful information. I've been working with Unity for a while now, and since most of the objects, like items and characters, have repeated behaviors, instead of using inheritance, I've been using separated scripts for a defined behaviors, which makes it so much easier for design. Instead of finding a way to make inheritance work and be flexible, I can just make a behavior script and attach it to the object. I thought I was being a little lazy there, but it may have not been a bad idea after all.

    • @zoran-horvat
      @zoran-horvat  6 หลายเดือนก่อน +1

      That sounds like a valid use of composition.

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

    Best videos ever!!!

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

    Unfortunately, in C++, you can have multiple inheritance, which means the Amphibian vehicle can inherit twice, once from Boat and once from GroundVehicle, then inside GetAverageSpeed it can call into the base classes.
    The problems still arise later because, unlike members inside an object, base classes can not be swapped at runtime, you can not change the base class of an object to be something else, some other object instance.
    Great video overall though!

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

    Best Video about composition! I'm your new Fan and Sub

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Thanks! I'm glad to hear you liked it.

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

    Zoren you are awesome,

  • @user-tk2jy8xr8b
    @user-tk2jy8xr8b ปีที่แล้ว +1

    Another case when inheritance brings lot of pain is injected deps, especially when you have 10+ descendants and add a new dep into the ctor of the base class

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

    Hey Zoran, thanks for the great content. Using your last example, how would you model vehicle specific properties without having to bloat the Vehicle class with functionality related to a single vehicle type, while also publicly exposing functionality only appropriate for the specific type. For example an airplane can have different wings (biplane, tandem wing, low wing, mid wing...), while a flying drone might have 4, 8,.. propellers instead. A boat might have sea anchors of different types, while that does not apply to car... At the end we do not want a method named "ApplyLandingConfiguration()" on a Car object. Of course we could have `car.LandingConfiguration?.Apply()` but the Vehicle class might become very large and confusing, if using composition only. Thinking out loud, but the ideal solution seems more like a combination of inheritance and composition, and constant refactoring while we add more types and functionality?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +6

      The rule of thumb is to keep entanglement under control. It is easy to imagine classes gradually becoming too diverse, precisely the way you described it. At some point, trying to find what they share in common, so to make certain downstream operations universal, becomes impossible, given the complexity of everything else around and inside the classes.
      ISP is often helping strike a good balance. Separate the classes, let them share nothing except private components they can use for their own purposes. Then let them implement an interface or two that will make them partially overlap, and hence applicable to some operations that should work on them.
      And when everything fails, we are back at square one - we might be forced to duplicate code of external operations if there is really no way to apply it to two or more classes that used to relate in the distant past.

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

      totalHours with sum operations. If one of MovingAbility is null, adding null to any value, will return null and not a value. Thus all ground vehicles, having flying ability as null, will always have null totalHours, correct? is it supposed to be so?

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

    Hi Zoran, love you content, could you make a series on DSA on c#

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Possibly yes, I'm not sure.

  • @user-nw8oi9vn9y
    @user-nw8oi9vn9y 8 หลายเดือนก่อน +1

    Great tutorial! Very helpful. Question: Sometimes I see some design patterns that are taught with inheritance. Should those be reworked to use composition instead?

    • @zoran-horvat
      @zoran-horvat  8 หลายเดือนก่อน +2

      On many occasions I prefer interfaces to base classes. When you transform it to composition, it would usually be a different pattern. But that comes with a twist: since composition can also be viewed as a manual kind of inheritance, then it turns out that all patterns of OOD boil down to two or three cases! Now that will be bothering you in the upcoming time.

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

    Around 13:35 you keep adding different abilities to the Vehicle class (composition). Is this how we extend the functionality (Open-closed principle) of the vehicle class? I mean is that the procedure when we want to add more functionality to the vehicle class later on?
    What I mean is I always thought composition means that we create separate class for ex "input", "engine" or "movement type" and next we create a "boat" class that as a movement type uses "water Movement" which ex detects if we are on water and can move, passes to it the value from the "input" and it performs the movement. For the car we use "Road movement" or whatever. That we create new classes that reuses the existing ones and basically are composed out of those.
    Thanks for this video!

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +3

      That is the good question. Depending on your priorities, you can orient the design in direction on supporting addition of more components without changing the class and disrupting its dependees. A design with a collection of abilities might be the way.
      However, such design would open the whole lot of other issues that stem from its increased abstractness. Like, how do we select abilities that apply to the terrain given in the query. That is simple now, at the expense of making a significant change at one point, maybe breaking some previous tests, etc.
      Bottom line is that any strategic decision in design is also a liability - a trade off. In the end, we select the design that satisfies what we consider important.

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

    Really interestering, this is the way Aristotle would prefer, do you have some book references about this design preference?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +1

      I can't think of any book on top of my head (other than GoF, which begins with this principle and applies it consistently). But you can find a lot of materials online.
      It could also be an interesting exercise to try writing code in some language that has no native support for inheritance.

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

    Could you also make something on the usage of volatile keywords and also explaining covariance and contra variance exactly

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +1

      Here is the video I made on covariance and contravariance: th-cam.com/video/Wp5iYQqHspg/w-d-xo.html
      Regarding volatile keyword, I am not sure that there is much audience for that topic.

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

      @@zoran-horvat thanks a lot, I believe volatile is too vague nobody uses it

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

    Thanks for the great video. I have a question about the GetAverageSpeed method: if we use it on any object that does not have all abilities that it will always return 0 right? so it is not quite useful. Was that just for demostration purposes or am I missing something? Thanks again

    • @zoran-horvat
      @zoran-horvat  10 หลายเดือนก่อน

      Actually, zero result is perfectly valid and useful in that case - it says you won't move. There was a much simpler design which calculates time instead of speed, but **that** design would fail in case that none of the transportation methods is available - it would have to return infinite time, which is inconvenient for TimeSpan.

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

    I can't help quoting my attorney when I ask her a legal question: "it all depends".

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

    Zoran, one side question, are you Hungarian? I feel like the name resembles! 😅🙂
    Greetings from Romania, Dan! 👋
    And thank you once again for your videos, I find them of great value!

    • @XKS99
      @XKS99 9 หลายเดือนก่อน +1

      If I were to guess he was a Serbian-Hungarian from Vojvodina.

  • @jean-pierreboies9749
    @jean-pierreboies9749 ปีที่แล้ว +2

    I'm sorry if you already answered that question before but what's the reason(s) you switched from Visual Studio to Visual Studio Code?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +3

      It is quicker compared to VS and I find great joy in tools that respond to commands without delay. I moved gradually to VS Code and now I think there is no project type in which I prefer VS anymore.
      It is worth noting, though, that two of my early attempts failed miserably.

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

    Hi Zoran, I have a question.
    So, let's say we create a Car.
    var car = Vehicles.CreateGroundVehicle(new MovingAbility(120));
    Console.WriteLine($"Average speed is: {car.GetAverageSpeed(120, 22, 3330)}");
    What would you expect this to print out?
    If it's a car, then it can not travel on air nor water, we can conclude the average speed would be 0 because the time needed would approach infinity to cover any of the two distances.
    However, what if we want to look for car.GetAverageSpeed(120, 0, 0);
    In this case, it should take into account that the car does not need to travel over water nor air and then print out the average speed. However, due to the nullability nature of the moving abilites, the totalHours will be null, hence rendering the GetAverageSpeed to be 0.
    Is this a mistake in my reasoning or a potential issue?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      I would expect any vehicle to return average speed zero if the track includes portions that it cannot travel, such as a flying distance applied to a car.

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

    Can we use LSP to solve this class inheritance problem also? If yes, how it solves it?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +1

      Object composition is closely related to LSP in the sense that the object's components themselves are usually polymorphic. However, there is a difference between designing a class hierarchy and designing polymorphic components - the latter normally have only one level of derivation.
      That is where LSP comes to play because all variants of a single component type must fully satisfy the base component's promise. If they cannot, that is probably an indication of a need to separate that concept into two components!

  • @user-nw8oi9vn9y
    @user-nw8oi9vn9y 8 หลายเดือนก่อน

    How could someone implement dependency injection into the composition version of the Vehicle class?

    • @zoran-horvat
      @zoran-horvat  8 หลายเดือนก่อน

      Depending on what the dependency object does, it would either be referenced by the containing object, or by the contained one. Object composition does not change much in the way we do dependency injection.

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

    I don't understand why Faster is implemented as an extension and not as a public static method of the MovingAbility class...

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Because of the shorter call syntax and because that operation does not belong to the MovingAbility class. Though I am not convinced that such a short name is communicating its purpose well.

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

    What if we need to introduce an engine "Ability"? There are gas, diesel, LNG, and electric. Since we have flying vehicles here, we might have jet engines. So at least 5 types. 5 more properties? Then we have a gas tank, or batteries for the electric motor. Another 2 properties?

    • @zoran-horvat
      @zoran-horvat  7 หลายเดือนก่อน

      A vehicle doesn't take fuel. Its engine or engines do. Therefore, I believe those would be the properties of objects contained in the vehicle, not the vehicle itself.
      Anyway, if you really plan to model a vehicle as we know it in the streets, where real cars have anything from 1,000 parts and above, it would make little sense to try to limit the number of components of such a complex model to a single-digit count.

  • @pharoah327
    @pharoah327 2 หลายเดือนก่อน

    Won't this cause us to always check each moving ability to see which is null and which isn't? Every time I want to do something with a vehicle object, I'll have spaghetti code if statements checking to see which ability it has that's not null. Don't get me wrong, this solution clearly has benefits over inheritance but let's be clear about the drawbacks too.

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

    If this is composition... Why you are injecting dependencies objects through factory constructor parameters (like aggregation) and not instantiating its composed objects inside the constructor (like composition)?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Composition vs. Aggregation is really not about who instantiates components and when. It is about the parts - in aggregation, parts make sense outside the whole; in composition, they don't.
      In the example from the video, a MovingAbility has no meaning outside a Vehicle. Therefore, Vehicle is a composition of MovingAbilities.
      Speaking of construction, it looks like anything makes sense except an aggregation that creates parts. Since each part is self-sufficient, it makes little sense to keep them locked inside the aggregation.
      Contrary to that, by injecting parts into a composition, especially if parts are polymorphic, we make the composition more flexible. Try to imagine a composition which knows all concrete part types and knows which one to use when - well, that would certainly be the most hardcoded and rigid design you have ever seen.

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

    the start of this example was really better suited for an interface rather than an abstract class (or even object composition) - I agree that many times composite function/objects are more suitable than inheritance, but I don't think this was a great example. If you are going to override all of the base class methods, there is literally no need to inherit. It is code duplication. Use an interface!

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      Isn't it off topic to ask for an interface in a demo which compares class inheritance with object composition? Like asking for an abstract class in a video on ISP.
      But, out of curiosity - what do you mean by "start of this example"? Start of the example has no features, so what timestamp would that start be?

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

      @@zoran-horvat I suppose you have a point. I just don't like the example. You were trying to show why composition is preferred over inheritance, but in your example, you should not have been using inheritance in the first place. I guess I get a little edgy about the whole argument because most people I encounter that argue against inheritance (and indeed, OOP in general) don't seem to know how to use it in the first place! Any tool can be misused.
      That said, I appreciate the video. And as I said, I do fundamentally agree that composition is very often the better way to go, especially in larger projects.

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

    That moving ability maybe would be solved with a nice enum? 😊

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +4

      Not really - each possibility would need to manage a different set of attributes. That asks for proper types.
      The true solution would be a union, similar to how C defined them but strongly typed. It is interesting that Rust is defining enums precisely that way: As a strongly typed union, each option with its own set of attributes, and with compiler guarantees of type safety.

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

      Not considered clean code and should be avoided.

  • @user-fh1mx6pz3r
    @user-fh1mx6pz3r 3 หลายเดือนก่อน

    is that the strategy design pattern???

    • @zoran-horvat
      @zoran-horvat  3 หลายเดือนก่อน

      It shares some similarities, but it does not share the motivation and usage. Therefore, it is not a strategy.

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

    I don’t like the vehicle containing these methods and think it violates open/closed principle as we need to change this to add more behaviours. I would look at a builder pattern for the moveability and inject it into vehicle.

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      You don't need such a heavyweight solution as a builder. The composition principle is showing a simpler solution - inject a polymorphic object that manages a certain ability and it is done, from point of view of the Vehicle class.

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

    You are an excellent teacher. Let me not degrade you by calling you a university Professor

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

    Are there any languages that support object composition as a first class feature?

    • @zoran-horvat
      @zoran-horvat  9 หลายเดือนก่อน +1

      Every language does.

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

      @@zoran-horvat I mean like function composition in f# is with the >> operator. I guess multiple inheritance or interfaces with default implementations serve a kind of composition as a language feature function.

    • @zoran-horvat
      @zoran-horvat  9 หลายเดือนก่อน

      @@XKS99 That is the dot operator in OO languages. Every language has it.

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

      @@zoran-horvat you can’t compose Class A with Class B to get Class C with the dot operator

    • @zoran-horvat
      @zoran-horvat  9 หลายเดือนก่อน

      @@XKS99 What does "compose class" mean in your comment? You compose objects, and then you assign them or return for further use.

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

    Doesnt youtube automatically deletes comments containing links?

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว

      That is a good question - I never tried!
      It is possible that I must approve a comment with link, which I would do
      Could you try to post a link to any GitHub repo here? We can test it.

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

      @@zoran-horvat I did post a couple of links. Dont see them after a few minuets.

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +1

      I have changed comments policy for this video to most liberal. Maybe that will help. Thank you for making a note on the problem.
      Unfortunately, I don't see any replies held for review yet. (I also suspect that some features regarding comments on TH-cam are indistinguishable from bugs...)

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

      Anytime I write something or reference to my github, youtube never posts my github links in comments. Not sure if this comment will go through.. 🤦‍♂

    • @zoran-horvat
      @zoran-horvat  ปีที่แล้ว +3

      @@vasoelias It appears that not only TH-cam deletes the comments, but it doesn't even send them to me for review. That's pretty aggressive stance towards external links.
      I have created a form where you can submit the links: codinghelmet.com/go/code-review-request

  • @vincecas3557
    @vincecas3557 6 หลายเดือนก่อน +1

    One thing that bothers me with videos that shows that says 'composition over inheritance' is they always show an example where they trip on the smallest problem and act likes there's no solution, or that it will become a mess.
    It always the same thing. Here's a apple, its a fruit! At this level, its simple! But what if the apple has wings?
    ??? Then its NOT a fruit?
    What I'm trying to say is that maybe there's an issue with your abstraction?

    • @zoran-horvat
      @zoran-horvat  6 หลายเดือนก่อน

      Any solution for the problem described in this video based on inheritance would exhibit combinatorial growth in the number of classes and code repetition caused by it. Which part of that sentence you don't understand?

    • @pharoah327
      @pharoah327 2 หลายเดือนก่อน

      I agree. He uses a contrived example to prove a point. The fact is that inheritance has plenty of use cases where it works fine and composition has plenty of use cases where it works as well. Choose the one that's right for your use case. I've created elegant solutions with inheritance in professional applications. Sure it has drawbacks but so does composition! There is no silver bullet. Every design decision has trade offs. A skilled developer considers all tools when making a decision and goes with the one that makes the most sense for their current problem.

  • @nikolazagorac8634
    @nikolazagorac8634 6 หลายเดือนก่อน +1

    What if you instead of having just the MovingAbility object composed, you also have a LightsAbility which controls the different kind of vehicle signalization, and a FuelAbility which controls fuel consumption, type and amount. In object composition you would have CreateDieselGroundVehicle(), CreateGasolineGroundVehicle(), CreateElectricGroundVehicle(), etc... and you would need to pass in the arguments all the different information: for eg. lights, engine, transmission etc. while in inheritance you would have a Vehicle abstract class which abstracts all those arguments as properties instead so a GroundVehicle would pass the FuelAbility into further abstraction so that the Mercedes_S_Class class would override that property and return a DieselFuelAbility which is created in the constructor and determined by a GroundVehicleData object passed in as an argument. I usually go a step further and have for each new type a separate data type and bind it with a generic argument from the base class, but then you also need an interface for the base class since referencing types with generic arguments requires you to know the exact argument type which means you cannot group them together. The inheritance would go something like this Vehicle : IVehicle where T : VehicleData, GroundVehicleData : VehicleData, GroundVehicle : Vehicle where T : GroundVehicleData, Mercedes_S_Class : GroundVehicle. Complexity cannot be avoided, you can only make your project simpler, which is often not what you require. I rule in favor of using both inheritance and composition, the Vehicle class should not know how the engine starts, instead it should have an Engine component which it abstracts so that a sub class can determine if it's a V engine, a rotary engine, a linear engine, etc. Anyways, this is a great video and I subscribed :)

  • @Manas-co8wl
    @Manas-co8wl ปีที่แล้ว +4

    One of those hardfast rules that just.. is. Unquestionable. Sometimes I wish all programming conumdrums were clear-cut as this.
    Also why do I like your voice so much

  • @EugeneS88-RU
    @EugeneS88-RU 5 หลายเดือนก่อน

    Haha, this is ethernal problem. Your example of resolve this isgood. but.. there is better solution - non OOP. ECS

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

    Now re-write it in Rust !

  • @blo0m1985
    @blo0m1985 วันที่ผ่านมา

    Code is not working if land, water or air is null, it will always return 0. You can't add null - it will return null.