O documento discute o Princípio da Inversão de Dependência (DIP), que estabelece que módulos de alto nível não devem depender de módulos de baixo nível, mas sim de abstrações, e abstrações não devem depender de detalhes, mas sim os detalhes das abstrações. O documento apresenta um exemplo de cálculo de salário antes e depois da aplicação do DIP.
1. Curso: Pós Graduação em Engenharia de Software Ágil
Disciplina: Programação Orientada a Objetos - Turma: 02 Calouros
Aluno: Guilherme Pereira de Souza Alves
Túlio Rezende de Castro Guimarães
Data: 11/06/2011 Professor: Edgard Davidson Costa Cardoso
DIP – The Dependency Inversion Principle
O Princípio da Inversão de Dependência estabelece duas definições:
1. Módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem
depender de abstrações; e
2. Abstrações não devem depender de detalhes. Os detalhes é que devem depender das
abstrações.
Em uma aplicação temos classes de baixo nível que programam operações básicas e classes
de alto nível que encapsulam a lógica complexa e depende das classes de baixo nível. Uma
maneira natural de programar esta aplicação seria escrever as classes de baixo nível
primeiramente e depois escrever as classes de alto nível mais complexa. Como as classes de
alto nível são definidas em função das outras previamente escritas, este parece ser o caminho
lógico para fazer esta programação. Porém, este não é um bom design, deixa o código rígido,
frágil e imóvel.
Para evitar tais problemas, podemos introduzir uma camada de abstração entre as classes de
alto nível e classes de baixo nível. Os módulos de alto nível contêm a lógica complexa que
não deve depender dos módulos de baixo nível. A camada de abstração não deve ser criada
com base em módulos de baixo nível. Os módulos é que devem ser criados com base na
camada de abstração.
De acordo com este princípio, a maneira de projetar uma estrutura de classe é começar a partir
de módulos de alto nível para os módulos de baixo nível:
Classes de Alto Nível -> Camada de Abstração -> Classes de Baixo Nível
Dois padrões de projeto ajudam a programar este princípio: o Template Method e o Stragety
Method. Estes dois padrões escondem as especificidades de um algoritmo tanto via herança
(Template) ou delegação via uma interface (Strategy).
2. Diagrama UML com dependência.
public class Trabalhador {
private Boolean temValeTransporte;
private Boolean temValeRefeicao;
private double salarioBase;
}
public class ValeRefeicao {
private double vr = 12;
public double retornarValorValeRefeicao(int diasNoMes){
return diasNoMes * vr;
}
}
public class CalculadoraSalario {
Trabalhador trabalhador;
private int diasUteisMes;
public void CalculadoraSalario(int dias, Trabalhador trab) {
trabalhador = trab;
diasUteisMes = dias;
}
Página 2 de 4
3. public double retornarSalarioBase(){
return trabalhador.getSalarioBase();
}
public double retornarSomaBeneficios(){
double total = 0;
if(trabalhador.getTemValeRefeicao())
{
total += new ValeRefeicao().retornarValorValeRefeicao(diasUteisMes);
}
if(trabalhador.getTemValeTransporte())
{
total += new ValeTransporte().retornarValorValeTransporte(diasUteisMes);
}
return total;
}
}
Diagrama UML com aplicação do Princípio da Inversão de Dependência.
public interface IBeneficios {
double retornarValorBeneficio(int diasNoMes);
}
public class ValeRefeicao implements IBeneficios {
Página 3 de 4
4. private double vr = 12;
public double retornarValorBeneficio(int diasNoMes){
return diasNoMes * vr;
}
}
public class Trabalhador {
private double salarioBase;
private List<IBeneficios> listaDeBeneficios;
public Trabalhador(){
listaDeBeneficios = new LinkedList<IBeneficios>();
}
public List<IBeneficios> getListaDeBeneficios() {
return listaDeBeneficios;
}
public void setListaDeBeneficios(List<IBeneficios> listaDeBeneficios) {
this.listaDeBeneficios = listaDeBeneficios;
}
}
public class CalculadoraSalario {
Trabalhador trabalhador;
private int diasUteisMes;
public void CalculadoraSalario(int dias, Trabalhador trab) {
trabalhador = trab;
diasUteisMes = dias;
}
public double retornaSalarioBase() {
return trabalhador.getSalarioBase();
}
public double retornaTotalBeneficios()
{
double total = 0;
for(IBeneficios b : trabalhador.getListaDeBeneficios())
{
total += b.retornarValorBeneficio(diasUteisMes);
}
return total;
}
}
Página 4 de 4