Don't Fall For The Inheritance Trap - Use This Instead
Вставка
- Опубліковано 15 вер 2024
- 💻Get the source code: go.dotnetacade...
In this video I explain the problems with inheritance, why you should stop using it and which is the much better alternative you should be using instead.
🔥Become a Senior C# Backend Engineer: juliocasal.com...
🗺️Get My Free .NET Backend Developer Roadmap: juliocasal.com...
Join me on Patreon: / juliocasal
Follow me on LinkedIn: / juliocasal
Follow me on X: x.com/julioc
#inheritance #csharp #dotnet
Thanks for the video. But I would like to point out a few things to make this better for people who watched it. By using composition, we comply the LSP but introduced complexity and frequent object creations. (Btw, you could also have used inheritance with it for "Walker" as it's common for all classes).
This could be better if we use interfaces. IoC is also needed for "Random" with transient lifetime DI.
Excellent video as always, Julio! The timing of this video is perfect considering we were just talking about this a few weeks ago haha. Keep up the great work!
Glad it was helpful, Ashton!
i have not seen composition described this way, i thought usually it would be something like: (using your nomenclature)
public class Archer: IMarkman, IWalker, IAttacker
{
// either define implementations or use predefined implementations and reference them
}
are there tradeoffs here, where your described version would be better??
@istovall2624 Check out my follow up video where I introduce interfaces: ua-cam.com/video/8CNy6Z5XLwM/v-deo.html
Please. Explain with product category no walk read person please
?
Liked the concept .. Really helpful.
Glad it was helpful!
Greate ! Thank you!
You're welcome!
As we declare a couple of behaviour classes, it got tightly coupled with Jobs. How to make it loosely coupled and also testable?
Rakib, like I mentioned at the end of the video, you can DI the required behaviors via the constructor of each job, and register them on program startup. You could also extract an interface for each behavior and DI that into jobs to help with testing.
Use dependency Injection and code against the interface, instead of the concrete class which would give you even more flexibility ;).
Here! ua-cam.com/video/8CNy6Z5XLwM/v-deo.html
Thank you so much about your tips.
May i use interface instead of behaviour class? what if i use it?
Could you clarify? Do you mean make the behavior class implement an interface and use the interface in the job? That would work too. Or you mean have each job implement the interfaces for each behavior? That would not be a good idea.
@@juliocasal i use interface for implement per behaviour, like ISlash, IFireCast, etc.. It's good?
So, having each behavior implement an interface, would be good. Then you can inject objects that implement that interface into each of your jobs constructors. But please don't implement the interfaces directly in your jobs, since that would generate code duplication.
Improve the code with dependency injection
Here: ua-cam.com/video/8CNy6Z5XLwM/v-deo.html
namespace ConsoleApp
{
public class Knight : Warrior
{
private readonly Werewolf _wereWolfSkills;
public Knight(Werewolf wereWolfSkills)
{
_wereWolfSkills = wereWolfSkills;
}
public void Shield()
{
Console.WriteLine($"Using shield.");
}
public void Rescue()
{
Console.WriteLine($"Rescuing princess.");
}
public void Transformation() => _wereWolfSkills.Transform();
}
}
namespace ConsoleApp
{
public class Warrior
{
private readonly Random random = new();
public void Walk()
{
Console.WriteLine($"Walking {random.Next(1, 10)} steps.");
}
public void Attack()
{
Console.WriteLine($"Attacking for {random.Next(1, 10)} points.");
}
public void Ultimate()
{
Console.WriteLine($"Using ultimate attack for {random.Next(100, 300)} points");
}
}
}
namespace ConsoleApp
{
public class Werewolf : Warrior
{
public void Transform()
{
Console.WriteLine($"Going crazy!");
}
public void Humanize()
{
Console.WriteLine("Going back to normal");
}
}
}
OK