I've got into dependency inversion principle and inversion of control just recently, and from what I currently know(correct me if I'm wrong) is that DIP states that
high level module/class should not be dependent upon the low-level module/class
both high and low-level module should not depend on details(not sure what this one means???), but abstractions(interfaces)
but when I was writing a simple program to implement this principle, i ran into a problem(will explain it later)
My program consist of an Inventory and Player class that implements "ICharacterable"
class Player : ICharacterable {
private int _health = 100;
public int Health{
get{
return _health;
}
}
public int HealthIncrease(int health){
//increase health
return _health + health;
}
}
class Inventory{
ICharacterable player = null;
//constructor injection
public Inventory(ICharacterable player) {
this.player = player;
}
//increase player health
public void UseHealthPotion(int health) {
player.HealthIncrease(health);
}
}
class Program{
static void Main(string[] args) {
Player john = new Player();
Inventory inv = new Inventory(john);
inv.UseHealthPotion(30);
Console.WriteLine(john.Health);
}
}
//interface
public interface ICharacterable {
int HealthIncrease(int health);
}
the problem is, the Console returns 100 instead of 130. I figure that the problem was caused due to the fact that I declared was injecting a ICharacterable type instead of Player(but that would violate the DIP), is there anyway I could do this? Thanks
You get bad result, because your method only returns result of the addition and not change a state of the object. Everything else is correct. Change it to:
You should only consider small replacement, in my opinion Player should contains Inventory, rather than vice versa. Then you will follow OOP design patterns and your code will be much better.
In this case Player = high-level class and Inventory = low-level class
Quick explanation:
Abstractions = interface or abstract class. Quite easy to understand, it's your ICharactable interface.
Details = implementation. It's your Inventory class. What makes your code compatible with this principle.