Better Grasp on Interfaces
c#
Solution
Here's the thing for me, I don't get why it's not a problem to just use the type Gadget and ConsoleLogger concrete methods. Why in this top layer does it still need to be a var of type ILogger and IGadget? I mean at this point I'm not seeing any need for polymorphism..but I"m missing the boat I guess here in my learning process.
The whole idea of `inversion of control` is to get the dependencies out of the classes, that uses them. Accodring the code you've pasted - the `Program` is highly coupled to specific classes. I even say - it is coupled to `implementation`!
So, when you rewrite that `Program` on using of interfaces - you are free in the future to use any interface impementation you want. Let's suppose you wanted to change `ConsoleLogger` to `SyslogLogger`, or even to `CompositeLogger` which writes to several storages.
With dependencies inverted (moved outside the class) - you can do that very simple and without any modifications. As usual - dependency container configuration is some of human-readable format, xml, for example. So for changing of your program behaviour (move from one - to another logger) - only thing you need is just to change one line in config file.
http://en.wikipedia.org/wiki/Inversion_of_control - this article describes the same thing but in correct english ))
UPD:
in that sample - `Program` depends on `ConsoleLogger` class. This means that the dependency is "inside" the class program. So when you move this dependency outside (for example - by passing the `ConsoleLogger` by function parameter) - it called inversion. And now that dependency is outside. Outside == `Program` now depends on some `ConsoleLogger` interface, not the class itself, and now `Program` does not take care how to instantiate that class object.
And `dependency container` is just a software that helps you to organize the relations/dependencies in a handy manner (as usual it is tree, dependency tree).
Problem
I have used a lot of abstract classes both for polymorphism, and obviously inheriting common function in subclasses. I'm trying to use interfaces more. Yes, it's also use for polymorphism..for example using an IMyInterface param in a method that can take any subclass that implements IMyInterface. Ok, now the thing I don't get though is why we should or always need to define our variables as IMyInterface instead of a type that has implemented that interface. Example, take a look at this article: http://weblogs.asp.net/sfeldman/archive/2008/02/14/understanding-ioc-container.aspx Ok, specifically this: ``` 17: private static void AppCode() 18: { 19: ConsoleLogger logger = new ConsoleLogger(); 20: Gadget gadget = new Gadget(logger); 21: gadget.TurnOn(); 22: gadget.TurnOff(); 23: } 24: } 25: } AppCode method (lines 19-22) is what we are interested in. A few question can be raised at this point: 1. Why logger is of type ConsoleLogger and not ILogger? Isn't this wrong? 2. Why gadget is of type Gadget and not IGadget? Same smell? 3. What if we need to move logger implementer to a different layer than the ConsoleApp? ``` Here's the thing for me, I don't get why it's not a problem to just use the type Gadget and ConsoleLogger concrete methods. Why in this top layer does it still need to be a var of type ILogger and IGadget? I mean at this point I'm not seeing any need for polymorphism..but I"m missing the boat I guess here in my learning process. Can someone explain why everyone wants to create interface params in your top layers for variables and assigning that variable to a type that has implemented that interface? Why not just Gadget and ConsoleLogger, the very concrete class you want to use in the first place? Yes Gadget and ConsoleLogger meet the contracts of the ILogger and IGadget...but I must be missing another reason here..fundamental reason. If I make no sense, it's because I don't really know how to describe my question but I feel this is pretty clear. Why use interface variables in a case like this? It's almost like what I've seen out there is once you need to use a concrete type that has implemented an Interface that it looks to me that you should always set it to an interface variable, not a variable type of that subclass. Is this right?