Difference between "depend on abstractions not concrete classes" and "program to an interface"
Asked Answered
L

2

11

The difference between these two principles is not clear for me. They just look like the same thing.

What is the difference if any?

Lammastide answered 3/4, 2014 at 9:0 Comment(0)
H
7

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.

Hammel answered 3/4, 2014 at 9:16 Comment(2)
Well, exactly this book led to this question as it introduces these two separate principles as something different but the explanation is not sufficient for me. At best I can see program to an interface to be already included in depend on abstractions which I see as just saying of strive for loose coupling in different words.Lammastide
@LeNoob I've updated my post, hope it's clearer now. I do agree with you in that the DI principle includes programming to an interface.Hammel
B
-2

In GoF Patterns book you can find definition of "interface". The set of all signatures defined by an object's operations is called the interface to the object. Interfaces in this book was declared in .h files and separated from implementation. So, given principles are synonymous.

.NET developers not familiar with GoF Patterns book can be confused by .NET interfaces.

Bondholder answered 3/4, 2014 at 10:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.