Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

What is the difference if any?

like image 824
ps-aux Avatar asked Apr 03 '14 09:04

ps-aux


People also ask

What is the difference between a concrete class and an interface?

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.

Is interface a concrete class?

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.

What is a concrete interface?

Noun. concrete interface (plural concrete interfaces) (object-oriented programming) An interface that extends another. quotations ▼

Can a concrete class implement an interface?

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.


1 Answers

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.

like image 117
dcastro Avatar answered Oct 21 '22 05:10

dcastro