Eu poderia citar e dissertar sobre as diversas vantagens. Que vão desde permitir que o contrato das classes sejam estabelecidos antes de suas implementações, até encapsular as classes concretas, deixando à mostra somente o que interessa: como utilizar a classe. Porém, já existem diversos artigos por aí explicando essas vantagens em detalhes.
O que tenho a dizer é que será muito mais fácil compreender estas vantagens se tivermos um exemplo de como e por quê isso funciona.
Normalmente, temos a noção de quais métodos nossa classe vai precisar possuir. Se você mal escreve a assinatura do primeiro método e já parte para a sua implementação, corre um sério risco de esquecer tudo o que havia planejado no início. Criar a Interface antes também ajuda a não deixar este problema acontecer.
ITipoDeArtefato.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dominio.Interfaces
{
public interface ITipoDeArtefato
{
void setCodigo(int codigo);
int getCodigo();
void setDescricao(string descricao);
string getDescricao();
}
}
IArtefato.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace Dominio.Interfaces
{
public interface IArtefato
{
void addImpactado(IArtefato artefato);
void removeImpactado(IArtefato artefato);
void addDependencia(IArtefato artefato);
void removeDependencia(IArtefato artefato);
int getCodigo();
string getDescricao();
void setCodigo(int codigo);
void setDescricao(string descricao);
ITipoDeArtefato getTipoDeArtefato();
void setTipoDeArtefato(ITipoDeArtefato tipoDeArtefato);
IDictionary<int, IArtefato> getListaImpactados();
IDictionary<int, IArtefato> getListaDependencias();
void setListaImpactados(IDictionary<int, IArtefato> listaImpactados);
void setListaDependencias(IDictionary<int, IArtefato> listaDependencias);
}
}