The difference between these two principles is not clear for me. They just look like the same thing.
What is the difference if any?
Interface is a blueprint for your class that can be used to implement a class ( abstract or not); the point is interface cannot have any concrete methods. Concrete methods are those methods which have some code inside them; in one word - implemented. What your interface can have is static members and method signatures.
A concrete class is a class that has an implementation for all of its methods. They cannot have any unimplemented methods. It can also extend an abstract class or implement an interface as long as it implements all their methods. It is a complete class and can be instantiated.
Noun. concrete interface (plural concrete interfaces) (object-oriented programming) An interface that extends another. quotations ▼
Concrete classes can also implement interfaces and extend abstract classes. We call the class a complete concrete class when it: In the case of implementing an interface, fully implements the properties and methods. In the case of extending an abstract class, implements the abstract methods.
From the book Head First Design Patterns, page 139, concerning the "Dependency Inversion" principle:
Dependency Inversion principle: Depend upon abstractions. Do not depend upon concrete classes.
At first, this principle sounds a lot like "program to an interface, not an implementation", right? It is similar; however, the Dependency Inversion Principle makes an even stronger statement about abstraction. It suggests that our high-level components should not depend on our low-level components; rather, they should both depend on abstractions.
A "high-level" component is a class with behaviour defined in terms of other "low level" components. For example,
PizzaStore
is a high-level component because its behaviour is defined in terms of pizzas - it creates all the different pizza objects, prepares, bakes, cuts, and boxes them, while the pizzas it uses are low-level components.
The following code follows the "program to an interface, not an implementation" principle, because you're calling Bake
and Deliver
on an abstraction. But it does not follow the DI principle, because your first block of code still depends on some concrete Pizza
types.
public class PizzaStore
{
public void OrderPizza(PizzaType type)
{
Pizza pizza;
switch(type)
{
case PizzaType.FourSeasons:
pizza = new FourSeasonsPizza();
//...
}
//do something with pizza
pizza.Bake();
pizza.Deliver();
}
}
By using the factory method pattern, or the abstract factory pattern, you're following both principles. Now you're programming against an abstraction and you're depending solely on abstractions. The pizza store depends on two abstractions: Pizza
and PizzaFactory
.
public class PizzaStore
{
private PizzaFactory factory;
public PizzaStore(PizzaFactory factory)
{
this.factory = factory;
}
public void OrderPizza(PizzaType type)
{
Pizza pizza = factory.CreatePizza(type);
//do something with pizza
pizza.Bake();
pizza.Deliver();
}
}
So yes, the DI principle includes the "program to an interface" principle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With