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).
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
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
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

Dip the dependency inversion principle

  • 1.
    Curso: Pós Graduaçãoem 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 comdependê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