"Programar em uma interface" significa que não depende de um tipo concreto para fazer seu trabalho , mas não especifica como você deve obter sua dependência.
O "Princípio da inversão de dependência" diz que um objeto não deve controlar a criação de suas dependências, deve apenas anunciar de que dependência ele precisa e deixar que o chamador o forneça . Mas não especifica se a dependência deve ser um tipo concreto ou uma interface.
Ilustrarei as diferenças com algum código C #.
O exemplo a seguir depende de um tipo concreto e controla a criação da própria dependência. Segue-se nem "programa para uma interface" nem "inversão de dependência":
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor()
{
_myThing = new MyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
O exemplo a seguir depende de uma interface, mas controla a criação da própria dependência. Segue "programa para uma interface", mas não "inversão de dependência":
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor()
{
_myThing = ThingFactory.GiveMeANewMyThing();
}
public void DoSomething()
{
_myThing.DoIt();
}
}
O exemplo a seguir depende de um tipo concreto, mas solicita que sua dependência seja criada e passada para ele. Segue "inversão de dependência", mas não "programa para uma interface":
public class ThingProcessor
{
MyThing _myThing;
public ThingProcessor(MyThing myThing)
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}
O exemplo a seguir depende de uma interface e solicita que sua dependência seja criada e passada para ela. Segue "inversão de dependência" e "programa para uma interface":
public class ThingProcessor
{
IMyThing _myThing;
public ThingProcessor(IMyThing myThing) // using an interface
{
_myThing = myThing;
}
public void DoSomething()
{
_myThing.DoIt();
}
}