Pular para o conteúdo principal

OOP - Interface e Implementação

OOP / SOLID - Interface Segregation Principle (ISP) / SOLID - Dependency Inversion Principle (DIP)

Uma interface define contratos (parecido com uma classe abstrata) mas sem definir nenhuma implementação. A principal diferença é que a classe abstrata pode implementar algo se ela quiser, enquanto uma interface não tem nada de implementação além do nome do método, o retorno e os params das funções.

public interface IRepo
{
void GetItem();
}

public class Repo : IRepo
{
public void GetItem() { // implementacao }
}

public class RepoFake : IRepo
{
public void GetItem() { // faz nada }
}

Podemos usar a classe de repositório direto em uma classe instanciando um objeto dele dentro do código mas isso é ruim porque aumenta o acoplamento. Se eu mudar a classe Repo, existe uma grande chance de quebrar a implementação na classe abaixo. Além disso, a criação de teste de unidade fica muito difícil porque eu vou precisar lidar com o comportamento do repositório. Chamamos esse método de composição concreta.

public class ImplementaRuim
{
public void MetodoRuim()
{
var repo = new Repo();
repo.GetItem();
}
}

Para melhorar isso, podemos usar a DI - Injeção de Dependência de modo que eu injeto o repositório no construtor e uso ele sem aumentar o acoplamento. Chamamos essa técnica de composição por interface.

public class ImplementaBom
{
private readonly IRepo _repo;

public ImplementaBom(IRepo repo) { _repo = repo; }

public void MetodoBom() { _repo.GetItem(); }
}

Isso facilita muito os testes de unidade porque podemos passar qualquer classe mockada no construtor da classe de teste abstraindo totalmente a camada de repositório.

public class TesteUniade
{
public void Teste1()
{
// aqui eu posso injetar a classe RepoFake o que torna a criacao
// de testes MUITO mais simples
var teste = new ImplementaBom(RepoFake)

// resto do teste
}
}

Referências