27 de jan de 2014

Movendo o cálculo da locação

Continuando nosso estudo sobre refactoring, podemo observar que o nosso novo método TotalLocacaoItem ficou fora do contexto. Nota-se que o método tem informações da locação, mas não tem informação sobre o cliente.

Isso nos lava a deduzir que o método está referenciado ao objeto errado. Na maioria dos casos um objeto precisa estar referenciado ao objeto que detém os dados que o método utiliza, portanto no nosso exemplo o método deveria estar no objeto Locacao.

type

  TCliente = class
  private
    FNome: string;
    FLocacoes: TLocacoes;
    procedure SetNome(const Value: string);
    function TotalLocacaoItem(Locacao: TLocacao): Double;
  public
    constructor Create(pNome: string);
    procedure AdicionaLocacao(Valor: TLocacao);
    function Relatorio: string;
    property Nome: string read FNome write SetNome;
    property Locacoes: TLocacoes read FLocacoes;
  end;


Para isso utilizamos o método Mover. Basta copiar o método para a classe Locacao, e faz os ajustes necessários. Depois é só compilar.




Para o exemplo que estamos trabalhando, após mover o método para classe lotação, é necessário retirar o parâmetro Locacao. E também, renomear  o método.

function TLocacao.TotalItem(): Double;
var
  TotalItem: Double;
begin
    TotalItem := 0;
    if Filme.CodigoPreco = TFilme.Regular then
    begin
      TotalItem := TotalItem + 2;
      if (DiasAluguel > 2) then
        TotalItem := TotalItem + ((DiasAluguel - 2) * 1.5);
    end
    else if Filme.CodigoPreco = TFilme.Lancamento then
    begin
      TotalItem := TotalItem + (DiasAluguel * 3);
    end
    else if Filme.CodigoPreco = TFilme.Infantil then
    begin
      TotalItem := TotalItem + 1.5;
      if (DiasAluguel > 3) then
        TotalItem := TotalItem + ((DiasAluguel - 3) * 1.5);
    end;
    Result := TotalItem;
end;


Agora podemos testar e ver como esse método é utilizado. Para fazer isso é só substituir o conteúdo do método TotalLocacaoItem, com a chamada do método criado na classe Lotacao.

function TCliente.Relatorio: string;
var
  Total, TotalLocacao: Double;
  PontosCliente: Integer;
  Resultado: String;
  Contador: Integer;
  Locacao: TLocacao;
begin
  Total := 0;
  PontosCliente := 0;
  Resultado := 'Registro de locação de ' + Nome + #13;
  // Determina total de cada locação
  for Contador := 0 to Locacoes.Count - 1 do
  begin
    Locacao := Locacoes.Items[Contador];
    TotalLocacao := Locacao.TotalItem();
    // Adiciona pontos de clientes
    PontosCliente := PontosCliente + 1;
    // Gera bonus porlocação de lançamento por dois dias
    if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then
      PontosCliente := PontosCliente + 1;
    //Mostra dados dessa locação
    Resultado := Resultado +  '|' + Locacao.Filme.Titulo + '|' +
    FloatToStr(TotalLocacao) + #13;
    Total := Total + TotalLocacao;
  end;
  //Adiciona Rodapé
  Resultado := Resultado +  'O total é: ' + FloatToStr(Total) + #13;
  Resultado := Resultado +  'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';
  Result := Resultado;
end;


Agora podemos compilar, testar e certificar que está funcionando exatamente como antes.


Nenhum comentário:

Postar um comentário