Become a patron and get access to source code and exclusive live streams: www.patreon.com/posts/stop-creating-if-81382624
@thygrrr6 ай бұрын
FINALLY a video that doesn't use "class Dog extends Animal" yet still meaningfully explores hierarchies *and* composition. (I am a strong proponent of OOP and Polymorphism, but object oriented modeling is only good if it doesn't try to directly mirror our human understanding of the problem domain, but instead approaches it orthogonally - just like the video)
@5cover Жыл бұрын
Finally, someone who doesn't look down on inheritance as the root of all evil! It has its strengths, even though it's not always appropriate. As a note, the sealed keyword is very useful when making this kind of single inheritance. It makes the intended design clear and provides a small performance boost (no virtual lookups)
@zoran-horvat Жыл бұрын
That is a good note about using the sealed keyword.
@anm3037 Жыл бұрын
You are the best programming concept teacher online! I listened to you while driving and I understood it without blinking on the screen 😅
@zoran-horvat Жыл бұрын
Haha, I'm not sure I can support that practice 🙂
@1992jamo Жыл бұрын
Completely agree. This is why I mostly use it for interfaces and use sealed.
@liviu_o Жыл бұрын
A very nice demonstration of the 'composition over inheritance' best practice. Thanks, Zoran!
@rammrras9683 Жыл бұрын
I think I found a precious resource! Keep the effort Sir, I enjoyed this video and I'll check the whole channel soon.
@TheChodex Жыл бұрын
I have seen many videos on KZbin and other sites about programming, but your videos have always had the biggest impact. So I would like to thank you for taking time to make these videos, and even release them for free! :)
@zoran-horvat Жыл бұрын
I'm glad you liked it. You should know that running a free channel is an exceptionally costly entertainment. I am finalizing preparations to introduce membership options to this channel, though the videos will remain free for all.
@user-tk2jy8xr8b Жыл бұрын
Those final hierarchies look exactly like discriminated unions from FP you mentioned (in Scala they would be defined with `case class` keywords)
@redcrafterlppa303 Жыл бұрын
I agree. The only exceptions are behavioral interface hierarchies. They allow for expression of complex types as their basic components. But class to class inheritance is the root of all evil and should be avoided. You can even see the lack of necessity in languages like rust that dropped class to class inheritance and a from the ground up developed interface based structure is much more flexible and doesn't suffer the same problems as class hierarchies suffer.
@funkdefied129 күн бұрын
Beautiful abstractions.
@obinnaokafor6252 Жыл бұрын
Another amazing video, thank you very much. This has shown the power of records in C#. Looking forward to seeing DU for C#
@alexr63 Жыл бұрын
Great video, thank you. But I cannot serialize/deserialize the book as JSON. Please can you help
@zoran-horvat Жыл бұрын
Being a domain model with the prospect of gaining more complexity, this class is not suitable for serialization. It is common to accompany such domain models with one or more flat models similar to those we define to support views, that will respond to communication requests.
@payman5581 Жыл бұрын
Great video. When you were showing the solution I thought to myself it looks like F# modeling and then you mentioned that we need to borrow that from functional programming. Nice.
@zoran-horvat Жыл бұрын
C# is getting very close to F# in that respect.
@TheOrovin Жыл бұрын
wow i wasn't aware that C# has a "record" type before.
@francoberaldi4028 Жыл бұрын
Hi great video! Altough im struggling with a specific case and im not sure it's the same as the video...would it be ok if i tried to describe it here? Thx
@styleisaweapon Жыл бұрын
Interfaces should only be used in the case of highly common data access themes, such as for simple iteration, and new ones generally should NOT be user-definable because thats the problem being solved. These common interfaces should be part of the language definition itself, for example in C# foreach() is generally used over the uglyness of driving an IEnumerable manually because one is both easier to read and to write. IEnumerable is intrinsic to C#, whereas something like IMyDatabaseRecord is intrinsic to obfuscation.
@zoran-horvat Жыл бұрын
IMyDatabaseRecord is not a good example - database records are normally concrete. How could we write them to a database if they are not? Interfaces have an important role in defining abstract concepts which are, in turn, a vital element in constructing deep domain models. Stating that custom interfaces should not be defined is a gross oversimplification of the programming theory.
@oddikaro8236 Жыл бұрын
Finally one person that masters OOP in the whole internet :)
@rhopsi-q6b Жыл бұрын
In a decent programming language (yes, they exist) one would then use traits/roles/aspects to construct a specific class. That can even be done dynamically if the language supports a meta model and/or reflection. But you're right: inheritance of classes is hell. Inheritance of roles, OTOH, is bliss.
@ghevisartor6242 Жыл бұрын
can you give me some example? i think Go does?
@drummsnikk5073 Жыл бұрын
Outstanding, glad i found your channel! 🔥
@zoran-horvat Жыл бұрын
I'm glad you found it useful.
@alpsavasdev Жыл бұрын
Is it something like composition over inheritance? I could not understand the exact implementation of this :/
@nikolaslijepcevic Жыл бұрын
No you didn't understand the point of this video. It showed us the excellent example when we should use the newest record keyword. I didn't know about this and thanks to this video I learned something new and I'm so happy now 😊😊😊
@alpsavasdev Жыл бұрын
@@nikolaslijepcevic but can’t you do the same thing using classes instead of records?
@nikolaslijepcevic Жыл бұрын
@@alpsavasdev Yes you can, and that is how we code before. But with record keyword your code is more simpler and readable. It provide us nice support for KISS principle
@Robert-yw5msАй бұрын
He's combining composition with inheritance.
@10199able Жыл бұрын
Do you think it's better to make such kind of modelling in F# and for other things (like UI or api) use C# ?
@zoran-horvat Жыл бұрын
That depends on whether your teammates know F# in the first place. My impression is that F# programmers, and functional programmers in general, are still rare. From what I have seen in companies I was consulting, it is either C# or F#, but never mixed together in the same team or project.
@Fikusiklol Жыл бұрын
Absolutely agreed. Excellent example.
@MrRobin4444 Жыл бұрын
I think the approach is good, I'm missing a little background information about the records. In the end, it's only classes that are used as properties at the end.
@biskitpagla Жыл бұрын
Picking up Go after some experience with OO-favored languages like C++, Python, and C# really helped me gain a better understanding of the problems of inheritance. You don't really need inheritance at all in a language that has 1. a way for structs/classes to "share implementation" of behavior and 2. another way to create subtypical relations (e.g., A can be substituted by B if B is a subtype of A) between them. Inheritance is actually meant to serve both these use cases in OO languages but leads to exponential complexity for a simple reason: there are way, way more scenarios where you need to share some implementation compared to scenarios where you need to create subtypes (more importantly, nested subtypes). This is hard to wrap your head around if you're still in OO-land but these things become crystal-clear when you look at tons of languages. Most forms of implementation sharing i.e., the scenario where you or, more probably, someone else have implemented some behavior for a struct/class but you want to reuse the same code for another class, don't require more than 1 level of "hierarchy" so to speak. Look at how mixins work in languages with multiple inheritance or how struct embedding elegantly solves this issue in Go, for example. But in most OO languages, you cannot do this without establishing a subtypical relationship between the classes first. This introduces a plethora of issues, paradoxes, brain-teasers to a problem that can be trivially solved by simply having these two things separate. I'm glad newer languages are going this way but this is still relevant for code written today with mainstream languages. Considering most design patterns really just exist to help you write code without inheritance, this isn't even a new idea.
@jimiscott Жыл бұрын
You can write everything in machine code - if it does the job then great. However, inheritance gives you another extremely tool, which when used correctly makes code clear and re-usable.
@marna_li Жыл бұрын
Thanks! Just shows that people are using inheritance in the wrong instances. There are so many ways of doing modeling. And you show that some attributes/traits can just be represented as objects attached via properties. They themselves can use inheritance - but that is limited to just one class so it will not affect much code further down the line.
@zoran-horvat Жыл бұрын
Precisely!
@theteachr Жыл бұрын
Algebraic Data Types FTW!
@pirati026 ай бұрын
Thia is so high level 👏👏
@CirwlosАй бұрын
Maybe a dictionary with keys like "ISSN" is more appropriate. The point of inheritance is to keep common code in a single place, to make it more maintainable. Not to add infinite properties to each class.
@chanep1 Жыл бұрын
perfect explanation, clear, detailed and consice
@ghevisartor624211 ай бұрын
How does this compare to your older video "Why Favor Object Composition Over Class Inheritance? A Deep Dive" ? The difference i find is that here it's more about properties and that other video is about behaviour? Sorry i'm struggling to put together the two in the example im working on.
@zoran-horvat11 ай бұрын
Composition is essentially about behavior, because inheritance is exclusively about behavior. In object composition, you delegate a call to the component. Properties are only a technical means to implement delegation (unless you see a property getter as a get method, in which case obtaining its value is also behavior).
@sandromagalli8587 Жыл бұрын
im just too stupid, i swear im trying to learn this and i see the reason for your case but then i have more abstract concept like a file operation and i get lost. It can be a copy, move, delete etc. I made a base version and then CopyOperation , MoveOperation, DeleteOperation etc inheriting it. But wait a copy or move, can have duplicates file, gotta ask the user how to precede. Ok do i store the function to apply with a modifier when the user choose replace or keep both files? Because keep both just require the other file to change name but the operation remain copy or move as before. Then there is an UploadOperation that require javascript (blazor IJsRuntime). All these little differences have made me make an inheritance hell, but i cant see how to group them with composition :/
@zoran-horvat Жыл бұрын
Start from understanding that composition can do everything inheritance can. Therefore, you can always come up with an identical solution using composition as the one you already have with inheritance. Then start thinking about all the issues caused by inheritance and look for the ways to remove them in the model based on composition.
@yaniv242 Жыл бұрын
what are records in c plus plus?
@DinoDiniProductions Жыл бұрын
Polymorphism is not unique to object orientated code. I first developed the idea independently in GUI code for a video game I in 68000 assembly in 1991.
@zoran-horvat Жыл бұрын
Polymorphism implemented via subtyping is object-oriented. But you are correct that it doesn't have to be that way. I used polymorphism in assembler almost 30 years ago, and it didn't differ much in results from what C++ did to augment C. Strictly speaking, *anything* that can stand in place of something else is acting polymorphically.
@craigsimon4312 Жыл бұрын
The solution is the simplicity.
@7th_CAV_Trooper8 ай бұрын
How can you build an AST / expression tree without class hierarchy?
@zoran-horvat8 ай бұрын
You can do it using a discriminated union. But AST is not a perfect example. It is a narrow problem, together with game development, system programming, embedded programming and the like. Each of these, and many more, is constrained in the ways we don't encounter in general programming, and so the general principles may not suit those problems well. Still, I don't see how a class hierarchy is good for implementing an AST.
@49riddickful Жыл бұрын
Zoran when are you finally going to fullfill your destiny and release an audiobook of Design Patterns (or any other awesome programming book) read by you? I mean that's where the views would be at. The potential it extraordinary :D
@zoran-horvat Жыл бұрын
Sounds intimidating :)
@pmcgee003 Жыл бұрын
I'd like to hear more about 'how a single level of inheritance relates to the FP approach' comment.
@0xAC4 ай бұрын
I think inheritance is just not something worth using. Interfaces and composition can do all what inheritance can and is worth doing. Reading code which heavily uses inheritance I always suffer. Switching back and forth between two or more classes dozens of time in order to understand a single simple method is a nightmare.
@kantagara Жыл бұрын
Wow, sjajno! :D Would learning functional programming (from your course :D ) help me as a develeoper to grasp these concepts better so that I don't end up with that awful design you showed in the first part of the video?
@jannishecht4069 Жыл бұрын
Haha, where is the book class in the second example? Asking for a friend.
@zoran-horvat Жыл бұрын
Tell your friend I had to hide the Book class because dwarfs wanted to take it away.
@mohsenmohammadi6324 Жыл бұрын
Please share the source code link
@zoran-horvat Жыл бұрын
I am preparing membership options and the source code will only be available to channel members. I hope you will understand. Running a KZbin channel is an expensive activity.
@StefanBarbara-q6e Жыл бұрын
Nice 🙂
@lextr31104 ай бұрын
While I agree that we should favor composition over inheritance.. it's plainly stupid to spit on OO hiearchy like this.. both play very well togheter with generics and FP... depending on your need...two layer hierachy hahaha kidding right?
@creo_one Жыл бұрын
Very important lesson, i'd replace abstract records for interfaces to not force any inheritance where it is not needed, that makes concepts like dependency injection and unit testing a lot easier