10 de mar. de 2010

Refactorings: Introduzir objeto parâmetro.

Salve

Direto ao ponto, imagine uma classe método que utilizem muitos parâmetros, por exemplo:

public class AluguelService {


    public List findAluguel(Date dataInicialContrato, Date dataFinalContrato,
                            Date dataInicialOcupacao, Date dataFinalOcupacao) {
        // pesquisa e regras de negócio aqui
    }

    public List findAluguelByStatus(Boolean status, 
                                    Date dataInicialContrato, Date dataFinalContrato,
                                    Date dataInicialOcupacao, Date dataFinalOcupacao) {
        // pesquisa e regras de negócio aqui
    }

    public List findAluguelByCliente(Integer idCliente, Date dataInicialContrato, 
                                     Date dataFinalContrato,
                                     Date dataInicialOcupacao, Date dataFinalOcupacao) {
        // pesquisa e regras de negócio aqui
    }

}


Esta classe é elegível a refatoração substituir parâmetros por objeto parâmetro: http://www.refactoring.com/catalog/introduceParameterObject.html

Neste caso, há sempre uma intervalo de tempo do contrato e ocupacao. Em primeiro lugar, poderia-se tratar os intervalos:


public class Intervalo {
    private Date dataInicial;
    private Date dataFinal;

    //Get's and Set's
}


E deixar a classe assim:


public class AluguelService {


    public List findAluguel(Intervalo contrato,
                            Intervalo ocupacao) {
        // pesquisa e regras de negócio aqui
    }

    public List findAluguelByStatus(Boolean status, Intervalo contrato,
                                    Intervalo ocupacao) {
        // pesquisa e regras de negócio aqui
    }

    public List findAluguelByCliente(Integer idCliente, Intervalo contrato,
                                     Intervalo ocupacao) {
        // pesquisa e regras de negócio aqui
    }

}


Acho que já deu "outra cara". Entretanto, se no domínio, o intervalo do contrato e ocupação andem sempre juntos, pode-se pensar em uni-los em um objeto parâmetro.


public class IntervaloAluguel {
    private Intervalo contrato;
    private Intervalo ocupacao;

    //Get's and Set's
}


Então, a classe ficaria assim:



public class AluguelService {


    public List findAluguel(IntervaloAluguel intervalo) {
        // faz pesquisa aqui
    }

    public List findAluguelByStatus(Boolean status, IntervaloAluguel intervalo) {
        // faz pesquisa aqui
    }

    public List findAluguelByCliente(Integer idCliente, IntervaloAluguel intervalo) {
        // faz pesquisa aqui
    }

}

Em uma prática mais Domain Driven Design poderia aplicar validações dos parâmetros nas classes parâmetro, por exemplo, tratar o IntervaloAluguel para que as datas sejam válidas, que a data de ocupacao esteja dentro do intervalo contrato, e assim por diante, deixando o a classe mais como um Value Object (não confundir com Transfer Object), se quiserem saber mais: http://www.infoq.com/presentations/Value-Objects-Dan-Bergh-Johnsson

Nenhum comentário: