tag:blogger.com,1999:blog-18297569238856803552024-03-05T07:16:45.598-04:00Info PraeiroInformática, desenvolvimento de software e análise de sistemas.Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-1829756923885680355.post-74760574635084305752014-01-27T21:10:00.000-03:002014-01-27T21:10:08.993-03:00Movendo o cálculo da locaçãoContinuando 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.<br />
<br />
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.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> TCliente = class</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FNome: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FLocacoes: TLocacoes;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetNome(const Value: string);</span><br />
<span style="color: red; font-family: Courier New, Courier, monospace;"> <b>function TotalLocacaoItem(Locacao: TLocacao): Double;</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"> public</span><br />
<span style="font-family: Courier New, Courier, monospace;"> constructor Create(pNome: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure AdicionaLocacao(Valor: TLocacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> function Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Nome: string read FNome write SetNome;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Locacoes: TLocacoes read FLocacoes;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<div>
<br /></div>
<br />
Para isso utilizamos o <u>método Mover</u>. Basta copiar o método para a classe Locacao, e faz os ajustes necessários. Depois é só compilar.<br />
<br />
<br />
<br />
<br />
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.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">function TLocacao.<span style="color: red;"><b>TotalItem</b>():</span> Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: red;"><b>TotalItem</b>: </span>Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if Filme.CodigoPreco = TFilme.Regular then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := TotalItem + 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (DiasAluguel > 2) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := TotalItem + ((DiasAluguel - 2) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Filme.CodigoPreco = TFilme.Lancamento then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := TotalItem + (DiasAluguel * 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Filme.CodigoPreco = TFilme.Infantil then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := TotalItem + 1.5;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (DiasAluguel > 3) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalItem := TotalItem + ((DiasAluguel - 3) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := TotalItem;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<div>
<br /></div>
<br />
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.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">function TCliente.Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total, TotalLocacao: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Contador: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := 'Registro de locação de ' + Nome + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Determina total de cada locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for Contador := 0 to Locacoes.Count - 1 do</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := Locacoes.Items[Contador];</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := <b><span style="color: red;">Locacao.TotalItem();</span></b></span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Adiciona pontos de clientes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Gera bonus porlocação de lançamento por dois dias</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Mostra dados dessa locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + '|' + Locacao.Filme.Titulo + '|' +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FloatToStr(TotalLocacao) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := Total + TotalLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Adiciona Rodapé</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'O total é: ' + FloatToStr(Total) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := Resultado;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<div>
<br /></div>
<br />
Agora podemos compilar, testar e certificar que está funcionando exatamente como antes.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaD1R7-cGmHAM6dfb8rXpMst9oSoyaLP4nOEQ-QYamVqiuK3X5iQTzFaMduZ9V1mmAhc8MX9oy2hDDmnt8oZIDBnWtY9iIFt5tHfoCuJfoPEPGVPWE-BNKpumbTNBgYXFRgwHsmeBngqc/s1600/teste100.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaD1R7-cGmHAM6dfb8rXpMst9oSoyaLP4nOEQ-QYamVqiuK3X5iQTzFaMduZ9V1mmAhc8MX9oy2hDDmnt8oZIDBnWtY9iIFt5tHfoCuJfoPEPGVPWE-BNKpumbTNBgYXFRgwHsmeBngqc/s1600/teste100.png" height="338" width="640" /></a></div>
<br />Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-4727294666869244342014-01-19T23:17:00.000-03:002014-01-19T23:17:42.629-03:00Renomeando variáveisMesmo com o facilitador do Delphi de extrair o método, eu mantive o primeiro modelo do método TotalLocacaoItem, onde o total de locação do item é resultado do método e sem utilizar os parâmetros do tipo var.<br />
<br />
Agora analisando o método que foi extraído, percebemos há variáveis que podem ter seus nomes melhorados.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">function TCliente.TotalLocacaoItem(Locacao: TLocacao): Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if Locacao.Filme.CodigoPreco = TFilme.Regular then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := TotalLocacaoItem + 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 2) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := TotalLocacaoItem + ((Locacao.DiasAluguel - 2) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Lancamento then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := TotalLocacaoItem + (Locacao.DiasAluguel * 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Infantil then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := TotalLocacaoItem + 1.5;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 3) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacaoItem := TotalLocacaoItem + ((Locacao.DiasAluguel - 3) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := TotalLocacaoItem;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<br />
Após renomear a variável, compilamos e rodamos o teste. Ok, sem erros, não estragamos nada.<br />
<br />
Vale apena o esforço para renomear variáveis. Sim, claro. Absolutamente. O bom código deve conseguir comunicar o que ele está fazendo de forma clara e precisa, e os nomes das variáveis são as chaves para garantir um código claro. Nunca devemos ter receio em modificar o nome das variáveis com objetivo de melhorar a qualidade do código. Utilize boas ferramentas de busca e substituição para facilitar o trabalho.<br />
<br />
Dica: Qualquer tolo pode escrever um código que o computador entenda. Bons desenvolvedores escrevem códigos que humanos conseguem compreender.<br />
<br />
Códigos que transmitem o seu propósito são muito importantes.<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-12046966400139496972014-01-19T15:54:00.001-03:002014-01-19T15:54:11.730-03:00Refactoring 1 - Decompondo e RedistribuindoÉ claro que o centro das atenções é o imenso método relatório. Ao se deparar com métodos muito extensos, o melhor a se fazer é decompor o método em pequenas partes. Pequenas partes de código tende a deixas as coisas mais gerenciáveis, são mais fáceis de trabalha-los e movimenta-los.<br />
<br />
A primeira fase do refactoring é dividir o método e mover as partes para classes que se adaptam melhor. O objetivo principal é facilitar a criação do método RealtorioHTML com a menor duplicação de código possível.<br />
<br />
O primeiro passo é encontrar um amontoado lógico de código e utilizar a <b style="text-decoration: underline;">Extração de Método</b>. Uma parte de código óbvia são as sequências de <i>if-else.</i> Essa para ser uma boa parte de código para ser isolada e ter seu próprio método.<br />
<br />
Quando extraímos um método, assim como em qualquer outro refactoring, precisamos saber o que pode dar errado. Se fizermos uma má extração, poderemos inserir um bug ao programa. Então, antes de fazer o refactoring, precisamos pensar em como fazer isso com segurança. Para isso precisamos seguir os itens de segurança.<br />
<br />
Primeiro precisamos localizar e identificar no fragmento de código todas as variáveis locais e parâmetros. No trecho de código que vamos extrair identificamos as seguintes variáveis: Locacao e TotalLocacao. A variável Locacao não é modificada pelo código, mas Contador e TotalLocacao são modificadas. Para qualquer variável que não é modificada pelo código eu posso defini-la no novo método como um parâmetro. Variáveis que sofrem modificação precisam de um cuidado maior. Se houver somente uma variável que sofre modificação, podemos retorna-la como resultado do método. A variável Contador, apesar de sofre modificação durante o código, ela não faz parte da regra de negócio, ela é apenas um artifício para navegar entre os itens do objeto Locacao, portanto não há necessidade de retorna-la fora do método. Sendo assim, posso definir a variável TotalLocacao como retorno do método.<br />
<br />
A seguir mostramos o código antes e depois do refactoring. Destacaremos em negrito as modificações.<br />
<br />
<table border="1">
<tbody>
<tr>
<td><div style="text-align: center;">
Antes</div>
</td>
<td><div style="text-align: center;">
Depois</div>
</td>
</tr>
<tr>
<td><span style="font-family: Courier New, Courier, monospace;">function TCliente.Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total, TotalLocacao: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Contador: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := 'Registro de locação de ' + Nome + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Determina total de cada locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for Contador := 0 to Locacoes.Count - 1 do</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> Locacao := Locacoes.Items[Contador];</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := 0;</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> if Locacao.Filme.CodigoPreco = TFilme.Regular then</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> begin</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := TotalLocacao + 2;</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> if (Locacao.DiasAluguel > 2) then</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 2) * 1.5);</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> end</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> else if Locacao.Filme.CodigoPreco = TFilme.Lancamento then</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> begin</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := TotalLocacao + (Locacao.DiasAluguel * 3);</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> end</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> else if Locacao.Filme.CodigoPreco = TFilme.Infantil then</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> begin</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := TotalLocacao + 1.5;</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> if (Locacao.DiasAluguel > 3) then</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 3) * 1.5);</b></span><br />
<span style="color: #ea9999; font-family: Courier New, Courier, monospace;"><b> end;</b></span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Adiciona pontos de clientes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Gera bonus porlocação de lançamento por dois dias</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Mostra dados dessa locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + '|' + Locacao.Filme.Titulo + '|' +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FloatToStr(TotalLocacao) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := Total + TotalLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Adiciona Rodapé</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'O total é: ' + FloatToStr(Total) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := Resultado;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span></td>
<td><span style="font-family: Courier New, Courier, monospace;">function TCliente.Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total, TotalLocacao: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Contador: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := 'Registro de locação de ' + Nome + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Determina total de cada locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for Contador := 0 to Locacoes.Count - 1 do</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := Locacoes.Items[Contador];</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #ea9999;"> <b>TotalLocacao := TotalLocacaoItem(Locacao);</b></span></span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Adiciona pontos de clientes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Gera bonus porlocação de lançamento por dois dias</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Mostra dados dessa locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + '|' + Locacao.Filme.Titulo + '|' +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FloatToStr(TotalLocacao) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := Total + TotalLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Adiciona Rodapé</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'O total é: ' + FloatToStr(Total) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := Resultado;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">function TCliente.TotalLocacaoItem(Locacao: TLocacao): Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #ea9999;"><b>TotalLocacao: Double;</b></span></span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if Locacao.Filme.CodigoPreco = TFilme.Regular then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 2) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 2) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Lancamento then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + (Locacao.DiasAluguel * 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Infantil then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 1.5;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 3) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 3) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <span style="color: #ea9999;"><b>Result := TotalLocacao;</b></span></span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<div>
<br /></div>
</td>
</tr>
</tbody></table>
<br />
<br />
Quando fazemos uma mudança desse nível, temos que compilar e executar o teste. Após executar, todos os teste rodaram sem erros.<br />
<br />
Digamos que na criação do método TotalLocacaoItem, tivéssemos colocar o retorno do tipo Integer ao invés de Double. Nesse caso, seria fácil pegar o problema no momento da compilação que estaria acusando erro de tipo de retorno. Esse é a essência do processo de refactoring pois o seria fácil e rápido encontrar o motivo do problema.<br />
<br />
Então fica a dica: Refatore o programa em pequenos passos. Se você cometer um erro, será fácil encontrar o bug.<br />
<br />
Na ferramenta Delphi XE3 temos o menu Refactor. (Não sei a partir de qual versão do Delphi já possui esse recurso). Se utilizarmos o item Extract Method (Shift+Ctrl+M), ele fará esse trabalho de extrair o método, gerando um novo método com o código selecionado. Conforme as imagens abaixo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXFsWDvF9XFhc4gC2NPx4jMALSxHPXLL-Kmu4zVtH4ufYIFBu7oOI6HqwSlBCIYLDNkjIZOp-eZKjfJY3xAbbKcsI30j25jrWTFu58GQIxfkY2I5WQ7EyUswH7aAT2yBOMiWX6MsaIDA8/s1600/em1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXFsWDvF9XFhc4gC2NPx4jMALSxHPXLL-Kmu4zVtH4ufYIFBu7oOI6HqwSlBCIYLDNkjIZOp-eZKjfJY3xAbbKcsI30j25jrWTFu58GQIxfkY2I5WQ7EyUswH7aAT2yBOMiWX6MsaIDA8/s1600/em1.png" height="339" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCUh6a2cMQcjGLY0KPLOJH5ZTAmANBkomTaAa3SoqFHA6qlU9IQtbEtaAdLL-V0zTNY7LRmBJDzjiGFEGzIwB5xgpGrwBCafw__kvqjN_2_chxg_couMiT_nLR8c3Ehy9vVSsvZfql2X4/s1600/em2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCUh6a2cMQcjGLY0KPLOJH5ZTAmANBkomTaAa3SoqFHA6qlU9IQtbEtaAdLL-V0zTNY7LRmBJDzjiGFEGzIwB5xgpGrwBCafw__kvqjN_2_chxg_couMiT_nLR8c3Ehy9vVSsvZfql2X4/s1600/em2.png" height="339" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgic2DNQXsKoDSV4VgLbGFBiulbRxaTA9EjdcAe4MhaW7HH9mifRLNLB2ulRCHjuBvcv4ou2hQnl-hFDv0pZb2Pi6rahWROvmVXQ9l15d1KWOf5bILZPaFtxO0iZdnVJnk6nGTF-UEDnXw/s1600/em3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgic2DNQXsKoDSV4VgLbGFBiulbRxaTA9EjdcAe4MhaW7HH9mifRLNLB2ulRCHjuBvcv4ou2hQnl-hFDv0pZb2Pi6rahWROvmVXQ9l15d1KWOf5bILZPaFtxO0iZdnVJnk6nGTF-UEDnXw/s1600/em3.png" height="339" width="640" /></a></div>
<br />
<br />
Gerando o código abaixo:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">function TCliente.Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total, TotalLocacao: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Contador: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := 'Registro de locação de ' + Nome + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Determina total de cada locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for Contador := 0 to Locacoes.Count - 1 do</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := Locacoes.Items[Contador];</span><br />
<span style="font-family: Courier New, Courier, monospace;"> <b><span style="color: #ea9999;">TotalLocacaoItem(TotalLocacao, Locacao);</span></b></span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Adiciona pontos de clientes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Gera bonus porlocação de lançamento por dois dias</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Mostra dados dessa locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + '|' + Locacao.Filme.Titulo + '|' +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FloatToStr(TotalLocacao) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := Total + TotalLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Adiciona Rodapé</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'O total é: ' + FloatToStr(Total) + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := Resultado;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TCliente.TotalLocacaoItem(<span style="color: #ea9999;"><b>var TotalLocacao: Double; </b></span>Locacao: TLocacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"><b> </b>TotalLocacao := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if Locacao.Filme.CodigoPreco = TFilme.Regular then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 2) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 2) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Lancamento then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + (Locacao.DiasAluguel * 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Infantil then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 1.5;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 3) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 3) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<div>
<br /></div>
Note que nesse caso, o método gerado, TotalLocacaoItem, não possui retorno. A ferramenta seta o parâmetro TotalLocacao como var e retorna nele mesmo o resultado da função. Esse recurso normalmente é usado quando precisamos que o método retorne mais de um valor, em todo o caso, no nosso exemplo o uso desse recurso não afeta em nada o refactoring, afinal o mais importante foi realizado, ou seja, extraiu o método TotalLocacaoItem do método Relatorio.<br />
<br />
E os testes continuam rodando sem erros:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8BBJh0Xj4E62suEKPBn1PpzXSjbq8LF7CmhI5hcqgoiYLOo5mKCKg6mFGA8YxX7mbFfQ_LcP1GfdYqiwk5fLGjiHuA-m4BvV0SNZ17KNfypb_Ycbulqeqj6A56oL3iz3dgZ-i_rJPo4/s1600/test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8BBJh0Xj4E62suEKPBn1PpzXSjbq8LF7CmhI5hcqgoiYLOo5mKCKg6mFGA8YxX7mbFfQ_LcP1GfdYqiwk5fLGjiHuA-m4BvV0SNZ17KNfypb_Ycbulqeqj6A56oL3iz3dgZ-i_rJPo4/s1600/test.png" height="338" width="640" /></a></div>
<br />
Continua no próximo post...Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-52919963675257815972014-01-18T15:05:00.001-03:002014-01-18T15:05:31.934-03:00Lista de Testes - CompletaConforme prometido segue a lista de testes completa. Bom, pelo menos acho que está completa.<br />
Procurei atender todas as situações de condicionais do método Relatorio. Todos os esteste estão executando sem erros. Agora, posso iniciar o refactoring, e se algum teste começar a falhar durante o refactoring, é porque algo está errado, e estou inserindo um bug no programa.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit uTesteLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">interface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">uses TestFramework, uCliente, uFilme, uAluguel;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TTestLocacao = class(TTestCase)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> published</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeInfantil1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeInfantil4Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeLancamento1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeLancamento2Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeRegular1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeRegular3Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure Locacao3FilmesDistintos5Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">implementation</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">{ TTestLocacao }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.Locacao3FilmesDistintos5Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeInfantil: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeRegular: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeLancamento: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeInfantil := TFilme.Create('Tarzan', TFilme.Infantil);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeLancamento := TFilme.Create('O Hobbit', TFilme.Lancamento);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeRegular := TFilme.Create('Máquina Mortífera I', TFilme.Regular);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(FilmeInfantil, 5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(FilmeRegular, 5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(FilmeLancamento, 1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|Tarzan|4,5' + #13 + '|Máquina Mortífera I|6,5' + #13 + '|O Hobbit|3' + #13 + 'O total é: 14' + #13 + 'Você ganhou: 3 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeInfantil.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeRegular.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FilmeLancamento.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeInfantil1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Tarzan', TFilme.Infantil);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|Tarzan|1,5' + #13 + 'O total é: 1,5' + #13 + 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeInfantil4Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Tarzan', TFilme.Infantil);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 4);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|Tarzan|3' + #13 + 'O total é: 3' + #13 + 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeLancamento1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|O Hobbit|3' + #13 + 'O total é: 3' + #13 + 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeLancamento2Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 2);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|O Hobbit|6' + #13 + 'O total é: 6' + #13 + 'Você ganhou: 2 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeRegular1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Máquina Mortífera I', TFilme.Regular);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|Máquina Mortífera I|2' + #13 + 'O total é: 2' + #13 + 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeRegular3Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> try</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Máquina Mortífera I', TFilme.Regular);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme, 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice' + #13 + '|Máquina Mortífera I|3,5' + #13 + 'O total é: 3,5' + #13 + 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: ' + Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> finally</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao.Free;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">initialization</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">TestFramework.RegisterTest(TTestLocacao.Suite);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end.</span>Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-10373136268459093282014-01-17T23:40:00.002-03:002014-01-17T23:40:28.158-03:00Primeiro passo do refactoring - Testes<br />
Sempre que for fazer o refactoring, o primeiro passo sempre é o mesmo. É necessário construir um conjunto de testes sólidos para a seção de código que será trabalhada. Os teste são fundamentais, pois mesmo que sigamos o refactoring de forma estruturada, ainda há o risco de inserir bugs no programa, afinal somos humanos e podemo cometer equívocos. Por isso precisamos de testes sólidos.<br />
<br />
Vamos a implementação de testes automatizados. O refactoring é uma ferramenta do TDD, e é por isso que estamos tratando desse assunto primeiro. Quando formos discutir TDD, vocês perceberão que já sabem tudo de TDD por que aprenderam TDD estudando refactoring.<br />
<br />
Em qualquer aplicação os testes são simples, rápidos de implementar e executar. É o conjunto deles que garantirá a efetividade da automatização de testes. Lembre-se para testar algo é preciso saber o que será testado, é preciso possuir um resultado ou valor esperado. O teste apenas vai executar algo, e consultar se o resultado esperado ocorreu ou não. O segredo do teste está a mensagem de retorno do resultado. Se o teste ocorreu conforme esperado, a mensagem pode ser um simples Ok. Mas se o teste deu errado, o próprio teste deve retornar dizendo o que deu errado. Qual o valor esperado que não foi encontrado, qual valor foi retornado no lugar do valor esperado. São essas informações que irão direcionar a solução para o problema detectado no teste. Por isso dizemos que o testes devem ser auto verificáveis. Se não fizermos dessa forma, perderemos tempo verificando números, consultando registros para saber onde o teste falhou.<br />
<br />
O refactoring se apoia totalmente nos testes. Nós vamos nos apoiar nos teste para nos dizer quando introduzimos um bug no programa. Por isso é essencial ter bons testes, testes abrangentes. Vale a pena gastar um tempo na implementação dos testes, pois eles lhe darão a segurança necessária para realizar as mudanças no programa.<br />
<br />
Vamos aos testes logo né!<br />
Para testar, sugiro a criação de testes que simule a locação de cada tipo de filme e com quantidade de dias de locação variados. Como o retorno do método Relatorio é uma string,o teste se concentrará na validação da string gerada pelo método em comparação com a string que esperamos que seja gerada. Podemos executar e simular todas as situações de testes e capturar as string geradas, em seguida basta adiciona-las ao teste. Vale ressaltar que o nosso exemplo nesse momento está correto e sem bugs, gerado os dados da forma que o usuário deseja, portanto faz todo o sentido utilizar esses dados na validação dos testes.<br />
<br />
Vou montar os testes, mas vou deixar uma amostra de alguns necessários para que possam basear.<br />
Continuo no próximo post.<br />
Até mais.<br />
<br />
Segue abaixo alguns testes (Esses são somente alguns testes, serão necessários mais testes, para ficar sólido e seguro):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7NDSeIfkfB1V80dX3OIzH13iaifM22wa2aZakPZ7xg8MI40B44Cca_0u8jChsa0swnwkmb8L-eg9cMIjZcCc74jX7FcCP0bwWl0SSik91O9Kyo4FGDMTSwSYRQfaZOjAqBkWgM2y7Up8/s1600/teste+locadora.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7NDSeIfkfB1V80dX3OIzH13iaifM22wa2aZakPZ7xg8MI40B44Cca_0u8jChsa0swnwkmb8L-eg9cMIjZcCc74jX7FcCP0bwWl0SSik91O9Kyo4FGDMTSwSYRQfaZOjAqBkWgM2y7Up8/s1600/teste+locadora.png" height="313" width="320" /></a></div>
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit uTesteLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">interface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">uses TestFramework, uCliente, uFilme, uAluguel;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TTestLocacao = class(TTestCase)</span><br />
<span style="font-family: Courier New, Courier, monospace;"> published</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeInfantil1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeInfantil4Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeLancamento1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure LocacaoFilmeLancamento2Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">implementation</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">{ TTestLocacao }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeInfantil1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Tarzan', TFilme.Infantil);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme,1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> '|Tarzan|1,5' + #13 +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'O total é: 1,5'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeInfantil4Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('Tarzan', TFilme.Infantil);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme,4);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> '|Tarzan|3' + #13 +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'O total é: 3'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeLancamento1Dia;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme,1);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> '|O Hobbit|3' + #13 +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'O total é: 3'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'Você ganhou: 1 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TTestLocacao.LocacaoFilmeLancamento2Dias;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente: TCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := TFilme.Create('O Hobbit', TFilme.Lancamento);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := TLocacao.Create(Filme,2);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente := TCliente.Create('Alice');</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Cliente.AdicionaLocacao(Locacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Cliente.Relatorio();</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Esperado := 'Registro de locação de Alice'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> '|O Hobbit|6' + #13 +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'O total é: 6'+#13+</span><br />
<span style="font-family: Courier New, Courier, monospace;"> 'Você ganhou: 2 pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Check(Resultado = Esperado, 'Falha no teste: Esperado: '+ Esperado + ' Realizado:' + Resultado);</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">initialization</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TestFramework.RegisterTest(TTestLocacao.Suite);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end.</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<br />Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-43018322743114016972014-01-16T23:48:00.000-03:002014-01-18T14:30:07.262-03:00Introdução ao Refactoring - Criando um cenárioComo mencionei anteriormente, nossa intenção e demonstrar o refactoring através de exemplos. Vamos procurar demonstrar como o refactoring funciona e demonstrar como ocorre o processo.<br />
<br />
Vamos pegar um exemplo pequeno, pois se utilizarmos um exemplo muito extenso, será necessário posts e posts para concluir. Realmente não faz sentido aplicar refactoring em programas muito pequenos, mas vamos interpretar que o exemplo a ser demonstrado é apenas uma pequena parte de um grande programa.<br />
<br />
O programa é muito simples. É um programa de videolocadora que calcula e imprime um relatório de um aluguel de video realizado por um cliente. O programa diz qual filme o cliente alugou e por quanto tempo. Ele então calcula o preço, que dependerá o tempo de aluguel e o tipo de filme.<br />
Há três tipos de filmes: regulares, infantil e lançamentos. Além de calcular o preço, o relatório exibe os pontos do cliente, que varia com o tipo do filme alugado.<br />
<br />
Algumas classes representam vários elementos da videolocadora, segue algumas:<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDL7D-DgcpdFgeTOVtpCNhTF9BEMYRwbqPlRr1tyewDehpyhZ8UqRS2p2oTPG3hM9LDbjIbYye3ZYqaOluja7Nw4xo6HKGY7dQHDoULuT_w_vSzELCcTktZlHR265WQCXbF8krthZgAuI/s1600/diagrama.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDL7D-DgcpdFgeTOVtpCNhTF9BEMYRwbqPlRr1tyewDehpyhZ8UqRS2p2oTPG3hM9LDbjIbYye3ZYqaOluja7Nw4xo6HKGY7dQHDoULuT_w_vSzELCcTktZlHR265WQCXbF8krthZgAuI/s1600/diagrama.png" height="92" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Em seguida o código de cada classe.<br />
<br />
<b>Filme</b><br />
Filme é um simples classe de dados<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit uFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">interface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme = class</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FTitulo: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FCodigoPreco: integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetTitulo(const Value: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetCodigoPreco(const Value: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> public</span><br />
<span style="font-family: Courier New, Courier, monospace;"> const Infantil = 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> const Regular = 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> const Lancamento = 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> constructor Create(titulo: string; precoCodigo: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Titulo:string read FTitulo write SetTitulo;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property CodigoPreco: integer read FCodigoPreco write SetCodigoPreco;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">implementation</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">{ Filme }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">constructor Filme.Create(titulo: string; precoCodigo: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure Filme.SetCodigoPreco(const Value: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FCodigoPreco := Value;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure Filme.SetTitulo(const Value: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FTitulo := Value;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end.</span><br />
<i><br /></i>
<b>Aluguel</b><br />
Aluguel representa o aluguel de filmes pelo cliente<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit uAluguel;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">interface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">uses uFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TAluguel = class</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FFilme: TFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FDiasAluguel: integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetFilme(const Value: TFilme);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetDiasAluguel(const Value: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> public</span><br />
<span style="font-family: Courier New, Courier, monospace;"> constructor Create(pFilme: TFilme; pDiasAluguel: Integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Filme: TFilme read FFilme write SetFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property DiasAluguel: integer read FDiasAluguel write SetDiasAluguel;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">implementation</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">{ TAluguel }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">constructor TAluguel.Create(pFilme: TFilme; pDiasAluguel: Integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Filme := pFilme;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> DiasAluguel := pDiasAluguel;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TAluguel.SetDiasAluguel(const Value: integer);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FDiasAluguel := Value;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TAluguel.SetFilme(const Value: TFilme);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FFilme := Value;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end.</span><br />
<br />
<i><br /></i>
<b>Cliente</b><br />
A classe cliente representa o cliente da loja. Assim como as outras classes ela possui dados e métodos assessores.<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit uCliente;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">interface</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">uses uAluguel, System.Classes;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">TLocacoes = TList;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">type</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> TCliente = class</span><br />
<span style="font-family: Courier New, Courier, monospace;"> private</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FNome: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FLocacoes: TLocacoes;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure SetNome(const Value: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"> public</span><br />
<span style="font-family: Courier New, Courier, monospace;"> constructor Create(pNome:string);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> procedure AdicionaLocacao(Valor: TLocacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Nome:string read FNome write SetNome;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> property Locacoes: TLocacoes read FLocacoes;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">implementation</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">{ TCliente }</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TCliente.AdicionaLocacao(Valor: TLocacao);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FLocacoes.Add(TLocacao.Create(Valor.Filme,Valor.DiasAluguel));</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">constructor TCliente.Create(pNome: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Nome := pNome;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">procedure TCliente.SetNome(const Value: string);</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FNome := Value;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;">end.</span><br />
<div>
<br /></div>
<i><br /></i>
A classe cliente possui um método que produz o relatório. A figura abaixo mostra as interações desse método. O código do método vem logo depois do diagrama.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpXDrPVUAmJMT8zws-dSnNQwS1MhBt6pvA53UpU0dqrLQuUzBF0-tah4UCz7feFVyESOanNfhO32_5Tb3K8MxudsP28ql0jNU-ogW25Wx9AmJhcRe5ujrdIdMAX_TGyKrrfoqa8WjxnhI/s1600/sequencia.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpXDrPVUAmJMT8zws-dSnNQwS1MhBt6pvA53UpU0dqrLQuUzBF0-tah4UCz7feFVyESOanNfhO32_5Tb3K8MxudsP28ql0jNU-ogW25Wx9AmJhcRe5ujrdIdMAX_TGyKrrfoqa8WjxnhI/s1600/sequencia.png" height="246" width="400" /></a></div>
<br />
<i><br /></i>
<i><br /></i>
<i><br /></i>
<span style="font-family: Courier New, Courier, monospace;">function TCliente.Relatorio: string;</span><br />
<span style="font-family: Courier New, Courier, monospace;">var</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total, TotalLocacao: Double;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado: String;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Contador: Integer;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao: TLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;">begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := 'Registro de locação de ' + Nome + #13;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Determina total de cada locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> for Contador := 0 to Locacoes.Count - 1 do</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Locacao := Locacoes.Items[Contador];</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := 0;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if Locacao.Filme.CodigoPreco = TFilme.Regular then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 2;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 2) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 2) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Lancamento then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + (Locacao.DiasAluguel * 3);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end</span><br />
<span style="font-family: Courier New, Courier, monospace;"> else if Locacao.Filme.CodigoPreco = TFilme.Infantil then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> begin</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + 1.5;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.DiasAluguel > 3) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> TotalLocacao := TotalLocacao + ((Locacao.DiasAluguel - 3) * 1.5);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Adiciona pontos de clientes</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> // Gera bonus porlocação de lançamento por dois dias</span><br />
<span style="font-family: Courier New, Courier, monospace;"> if (Locacao.Filme.CodigoPreco = TFilme.Lancamento) and (Locacao.DiasAluguel > 1) then</span><br />
<span style="font-family: Courier New, Courier, monospace;"> PontosCliente := PontosCliente + 1;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Mostra dados dessa locação</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + '\t' + Locacao.Filme.Titulo + '\t' +</span><br />
<span style="font-family: Courier New, Courier, monospace;"> FloatToStr(TotalLocacao) + '\n';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Total := Total + TotalLocacao;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> end;</span><br />
<span style="font-family: Courier New, Courier, monospace;"> //Adiciona Rodapé</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'O total é: ' + FloatToStr(Total) + '\n';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Resultado := Resultado + 'Você ganhou: ' + FloatToStr(PontosCliente) + ' pontos';</span><br />
<span style="font-family: Courier New, Courier, monospace;"> Result := Resultado;</span><br />
<span style="font-family: Courier New, Courier, monospace;">end;</span><br />
<div>
<br /></div>
<i><br /></i>
<b>Comentários sobre o código do programa</b><br />
<b><br /></b>
Qual sua opinião sobre o código programa? Você pode dizer que ele não está bem implementado, e que certamente não está orientado a objetos. Para um simples programa como esse, isso realmente não importa. Não existe nada de errado com um programa feito rapidamente e bagunçado. Mas se esse código representa um fragmento de um sistema mais complexo, aí sim, temos sérios problema com esse programa.<br />
A rotina relatório na classe cliente está muito extensa e faz muitas coisas. Muitas dessas coisas deveriam estar sob responsabilidade de outras classes.<br />
<br />
Mesmo que o programa funcione bem. Isso não é apenas um julgamento de quem não gosta de códigos feios e mal feitos. Para o compilador não importa onde o código está mal feito e onde está bem feito. Mas se precisar realizar uma alteração no sistema, haverá um humano envolvido, e para humanos isso importa.<br />
Um código mal organizado e complicado para se alterar. É complicado por que ele precisa saber onde as mudanças são necessárias. E se é complicado identificar onde precisa ser alterado, existe então uma chance muito grande do desenvolvedor cometar um equívoco e acabar gerando um bug no sistema.<br />
<br />
Vamos supor que nesse caso o usuário deseje algumas mudanças no sistema. A primeira mudança que ele deseja é que o relatório seja emitido no formato html. Considere o impacto dessa mudança.<br />
Como você pode observar no código é impossível reaproveitar qualquer comportamento do atual método relatorio para um relatório hmtl. A unica opção que você possui é copiar o método atual, e criar um novo método. Nada trabalhoso, no entanto, o comportamento ficará duplicado.<br />
<br />
E se mudar as regras de cálculo? Você terá que ajustar o método <span style="font-family: Courier New, Courier, monospace;">Relatorio </span><span style="font-family: inherit;">e o método </span><span style="font-family: Courier New, Courier, monospace;">RelatorioHTML</span><span style="font-family: inherit;">, para que a mudança atenda os dois relatórios.</span><br />
<span style="font-family: inherit;">O problema do copiar colar, vem quando você precisa fazer alguma mudança. Se você está escrevendo um programa pequeno, e que não sofrerá mudanças, o copiar colar atende muito bem. Mas se o programa tem um tempo de vida longo, o copiar colar pode se tornar uma grave ameaça.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Isso leva a uma segunda solicitação de mudança. Os usuários quem mudar a forma de classificar os filmes, mas eles não se decidiram ainda de como será essa nova classificação. Eles tem várias solicitações de mudanças em mente. Essas mudanças afetam diretamente os preços das locações de filmes e o cálculo de pontuação de clientes. E você na sua experiência de desenvolvedor, sabe que os usuários vão continuar solicitando mudanças.</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Você pode tentar fazer poucas modificações, que sejam possíveis, no código e depois de tudo funcionar conforme esperado. Relembrando a máxima da velha engenharia: "Se ainda não deu problema, não conserte." O programa pode realmente não dar problema, mas isso dói. Isso faz a sua vida mas difícil, pois você encontra dificuldades em fazer as mudanças que o usuário solicita. É nessa hora que entra o refactoring!</span><br />
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Dica: Quando você tem que adicionar um novo recurso ao programa, e o código do programa não está estruturado de forma conveniente para adicionar o novo recurso, primeiro refatore o programa de modo que a adição do recurso fique mais fácil, e só então adicione o novo recurso.</span><br />
<span style="font-family: inherit;"><br /></span>
<br />
<b><br /></b>
<i><br /></i>
<i><br /></i>Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-5957726144562164222014-01-16T00:11:00.001-03:002014-01-16T00:12:45.219-03:00DUnit - "Instalação"<br />
Dunit<br />
<br />
A Dunit é uma framework de testes específica para Dephi. Ela foi inspirada na JUnit, framework de testes voltado para Java, desenvolvido por Kent Beck (olha ele aí de novo)e Erich Gamma. No entanto a ferramenta evoluiu e hoje usa muito mais o potencial da IDE Delphi visando ser cada vez mais útil para os utilizadores do Delphi.<br />
<br />
Como vamos tratar de Refactoring e Desenvolvimento Orientado a Testes, faz necessário utilizar uma ferramenta facilite a execução desses testes. Por isso vamos iniciar com a instalação da Dunit.O exemplo que será descrito a seguir está usando o Delphi XE3, mas a instalação pode ser realizada em qualquer versão do Delphi.<br />
<br />
Link para Download da DUnit: <a href="http://sourceforge.net/projects/dunit/">http://sourceforge.net/projects/dunit/</a><br />
<br />
<span style="text-indent: -18pt;"><br /></span>
<div>
<span style="text-indent: -18pt;"><br /></span></div>
<div>
1. Descompacte o arquivo dunit-9.0.3.zip em uma pasta qualquer.<br />
<br />
<div class="MsoListParagraph" style="mso-list: l0 level1 lfo1; text-indent: -18.0pt;">
<o:p></o:p></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-EU5Rz-sc01RrcxYcr_f91oPVJQTsgf9HnoGcaUhgiMNa6UwRGc7bJhhyXUZRa5KeT9jn9Yo6eB2iXTGvYCTZQYj0m80MaqDfAvZzLQl34ZQoysX9L4NQvDXYjjUqQi2roXCvvqN4Bto/s1600/pasta.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-EU5Rz-sc01RrcxYcr_f91oPVJQTsgf9HnoGcaUhgiMNa6UwRGc7bJhhyXUZRa5KeT9jn9Yo6eB2iXTGvYCTZQYj0m80MaqDfAvZzLQl34ZQoysX9L4NQvDXYjjUqQi2roXCvvqN4Bto/s1600/pasta.png" height="340" width="400" /></span><span style="font-size: 7pt; margin-left: 1em; margin-right: 1em; text-indent: -18pt;"> </span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<o:p><br /></o:p></div>
<div class="separator" style="clear: both; text-align: center;">
<o:p><br /></o:p></div>
2. Adicionar a pasta “src” na library do Delphi.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlqBlIGyxH74Er587nYagxiKEOpvZGCrPwDUtsySpYVqYsWGCE4hMSNzxPONfxl58P3pWs4w5Pd5Vyd6fHuGPBB4_4viokKDASDcTh7UhDO95tM5-87a4HjrvHSLYymHWk53596WXkX2Y/s1600/library.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlqBlIGyxH74Er587nYagxiKEOpvZGCrPwDUtsySpYVqYsWGCE4hMSNzxPONfxl58P3pWs4w5Pd5Vyd6fHuGPBB4_4viokKDASDcTh7UhDO95tM5-87a4HjrvHSLYymHWk53596WXkX2Y/s1600/library.png" height="331" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
3. Por incrível que pareça, está instalado!<br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />
<br />
Agora vamos testar a framework.<br />
<br />
Crie um novo projeto no Delphi. Feche a unit1 sem salvar. Salve o que restou, e nomeie como Projeto1Teste.dpr.<br />
<br />
Adicione uma nova unit, através do menu File| New| Unit. Este e o arquivo que conterá o caso de teste, portanto nomeie-o como Projeto1CasoTeste. Na cláusula uses da interface (acima da palavra interface) adicione a referência a TestFramework. (uses TestFramework).<br />
<br />
Declare um classe com o nome PrimeiroCasoTeste descendendo de TTestCase. Acrescente a classe um método PrimeiroTeste, conforme abaixo, atente a seção intialization:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">unit Projeto1CasoTeste;<br /><br />interface<br /><br />uses TestFramework;<br /><br />type<br /><br /> TPrimeiroCasoTeste = class(TTestCase)<br /><br /> published<br /><br /> procedure PrimeiroTeste;<br /><br /> end;</span><span style="font-family: 'Courier New', Courier, monospace;">implementation</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">{ TPrimeiroCasoTest }</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">procedure TPrimeiroCasoTeste.PrimeiroTeste;</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">begin</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;"> Check(1+1=2, 'Falha matemática catastrófica!');</span><span style="font-family: Courier New, Courier, monospace;"><br /></span><span style="font-family: 'Courier New', Courier, monospace;">end;</span><span style="font-family: Courier New, Courier, monospace;"><br /><br />initialization</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br />TestFramework.RegisterTest(TPrimeiroCasoTeste.Suite);<br /><br />end.</span><br />
<br />
Selecione o menu Project | View Source e adicione TestFramework e GUITestRunner na clásula uses.Remova o código default da aplicação e adicione o código abaixo:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;">program Project1Test;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br />uses<br /><br /> Vcl.Forms,<br /> Projeto1CasoTeste in 'Projeto1CasoTeste.pas',<br /> TestFramework,<br /> GUITestRunner;<br /><br />{$R *.res}<br /><br />begin<br /><br /> Application.Initialize;<br /> GUITestRunner.RunRegisteredTests;</span></div>
<div>
<span style="font-family: Courier New, Courier, monospace;"><br />end.</span><br />
<br />
Ao executar o programa, será exibida a interface visual da Dunit, para execução de testes, conforme imagem abaixo:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihhOCW_tqWWcr7L03mwXPII3rys_feKbGF-_QubcR9hAV4dooogDFaMFKhH0kdQdgzLcjTD2BiNLNwSldnwRNg46gLCU2a-clM5DxOthkyNpWCVDiBFbyU00-gN_Rek-KSaSdGAU-6lRQ/s1600/dunitinit.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihhOCW_tqWWcr7L03mwXPII3rys_feKbGF-_QubcR9hAV4dooogDFaMFKhH0kdQdgzLcjTD2BiNLNwSldnwRNg46gLCU2a-clM5DxOthkyNpWCVDiBFbyU00-gN_Rek-KSaSdGAU-6lRQ/s1600/dunitinit.png" height="400" width="397" /></a></div>
<br />
<br />
<div class="separator" style="clear: both;">
<br /></div>
<br />
Em seguida, ao clicar no ícone para execução de testes (seta verde apontada para direita) a Dunit realizará o teste descrito.<br />
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOfj4mWdHT4JBlEBTpz76s7yvkyk1GNlOeOjRlHXfHxt5Ghuta8IIFRvibDMGCDq7n_Aiu5UB6mnBLhypTVW_FrCnmKNM1fZ17hm3nVbkfEybA_j17LZyzDMi-iRiXUK_1__H05aIi-N8/s1600/dunitexecuted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOfj4mWdHT4JBlEBTpz76s7yvkyk1GNlOeOjRlHXfHxt5Ghuta8IIFRvibDMGCDq7n_Aiu5UB6mnBLhypTVW_FrCnmKNM1fZ17hm3nVbkfEybA_j17LZyzDMi-iRiXUK_1__H05aIi-N8/s1600/dunitexecuted.png" height="390" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-indent: -24px;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
<div class="separator" style="clear: both; text-indent: -24px;">
<span style="font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span></div>
Pronto! DUnit instalada e testada. Próximo post vamos ao refactoring e a aplicação de TDD.<span style="text-indent: -24px;">
</span></div>
Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com1tag:blogger.com,1999:blog-1829756923885680355.post-20797867485849145332014-01-15T21:35:00.000-03:002014-01-18T14:29:45.264-03:00Aplicando Refactoring e TDD com DelphiNas últimas semanas dediquei a literaturas técnicas onde li o livro do Kent Beck - Test Driven Development by Example (Desenvolvimento orientado a testes através de exemplos, na tradução ao pé da letra). Atualmente estou lendo Martin Fowler - Refactoring: Improve the Design of Existing Code (Refatoração: Melhorando o Design de Código Existente, tradução ao pé da letra).<br />
<br />
O Kent Beck é muito conhecido na comunidade Agile. Ele é um dos precursores, e um dos autores do manifesto do movimento ágil.<br />
Mas meu objetivo aqui não e falar dos autores, mas sim dividir o conhecimento com vocês.<br />
Os livros, como são baseados em exemplos, possuem exemplos completos da prática do TDD e do refactoring, mas todos esses exemplos estão na linguagem Java.<br />
<br />
O desejo é transmitir esse conhecimento para o leitor que faz uso da IDE Delphi. Sou usuário há anos do Delphi, e o que ouço por aí, é ver as pessoas dizendo que o Delphi não é orientado a objetos, que Delphi não permite seguir nenhum paradigma de design, e etc. Assim como também vejo muita gente que trabalha com Delphi achar que orientação à objetos é ficar colocando componentes de tela em um formulário e interagir com eles através do código. Pobres coitados!<br />
<br />
Bom, eu vou tentar nos próximos posts, refazer e explicar em português os ensinamentos repassados pelos livros, e aplicar os exemplos em Delphi. Por que? Porque esse assunto voltado em Delphi é escasso, e as pessoas insistem em achar que em Delphi nada é possível.<br />
<br />
Vamos lá?<br />
<br />
Os posts serão organizados da seguinte forma:<br />
<br />
<br />
<ol>
<li>Instalação da Dunit no Delphi</li>
<li>Exemplo de refactoring com TDD</li>
<li>Definição de conceitos básicos.</li>
</ol>
<div>
Estanho né? Vamos começar com exemplos e não com definições!</div>
<div>
Martin Fowler diz no seu livro que quando vai a uma palestra onde será divulgado um novo conceito, normalmente o palestrante inicia pelos conceitos. Definição de conceitos sem você saber do que se trata é muito chato e muitas vezes da até sono. Então é só na hora dos exemplos práticos que o Martin acorda e confere pra que serve aquilo.</div>
<div>
<br /></div>
<div>
Eu não queria ser um palestrante para um cara desses nem pensar. Mas ele tem toda a razão. E por isso, vamos começar com a prática. E depois você decide se vale a pena conhecer os conceitos ou não.</div>
<div>
Então é isso! Até o Próximo post.</div>
<div>
<br /></div>
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com2tag:blogger.com,1999:blog-1829756923885680355.post-17515773229323624652011-01-13T02:05:00.000-03:002011-01-13T02:05:17.973-03:00Gestão de demandas<div class="MsoNormal">O Governo Federal pode ser considerado como uma grande empresa. Assim como uma empresa privada necessita de controles, gestão, gerência e diretorias, o Governo não é diferente. Dessa forma, quando estamos trabalhando com processos, o Governo pode ser uma boa fonte de consulta. Devido ao seu tamanho e sua complexidade, o Governo pode já ter implementado e estudado um processo que você pode estar procurando conhecer melhor.</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Pesquisando o site o do Ministério do Planejamento (<a href="http://www.planejamento.gov.br/">www.planejamento.gov.br</a>) você pode encontrar não somente informações sobre o Ministério e suas ações, mas como também, se beneficiar das informações relacionadas a planejamento, gestão estratégica e até softwares gratuitos desenvolvidos para atender as necessidades do mais variadas setores do Governo (<a href="http://www.softwarepublico.gov.br/">www.softwarepublico.gov.br</a>).</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Pesquisando a parte de softwares, dois projetos me chamaram a atenção. O primeiro é o SGD – Sistema de Gestão de Demandas (<a href="http://www.softwarepublico.gov.br/ver-comunidade?community_id=51261">http://www.softwarepublico.gov.br/ver-comunidade?community_id=51261</a>), e o segundo é o OASIS – Sistema de Gestão de Projetos, Demandas, e Serviços de Tecnologia da Informação (<a href="http://www.softwarepublico.gov.br/ver-comunidade?community_id=8566986">http://www.softwarepublico.gov.br/ver-comunidade?community_id=8566986</a>).</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">O SGD foi desenvolvido especialmente para atender as necessidades da TI, onde segundo o site do projeto explica que a função principal do sistema é transformar as demandas internas em projetos que são controlados pelo escritório de projetos, melhorando consequentemente a qualidade do atendimento do serviço publico.</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">O software é destinado não somente para os órgãos públicos, mas inclusive para empresas que desejam controlar suas demandas. Não vou explicar aqui o funcionamento do software, mas sim, o seu embasamento ideológico.</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">O sistema é baseado em dois conceitos muito atuais: Processos internos transformados pela tecnologia e o Processo de Gestão do Conhecimento. É notório que em vários setores, tanto privados quanto públicos, os processos foram transformados ou remodelados pela tecnologia. O que era manual, lento e sujeito a falhas humanas, foi adaptado para um processo, eletrônico, ágil e com menor incidência de falhas. É evidente também que o conhecimento passou a ser peça fundamental em qualquer trabalho ou ação a ser realizada. Gerenciar esse conhecimento, de modo que ele possa ser propagado, compartilhado, distribuído e aprimorado é essencial para a continuidade de qualquer negócio, trabalho ou projeto.</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">A gestão de demanda tem a função de coordenar, controlar todos os fatores de demanda, de forma que o sistema produtivo possa ser eficientemente utilizado e as datas de entregas dos produtos possam ser pontualmente atendidas.</div><div class="MsoNormal"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXkTCVTTRG_-DlIJUmZ_EFi7l3PMLTeVaFGKwW3TfLouG8-zbj9vSMOCjb6nmuixIbC63SdUGxzxj7reffObPKiU5xQ5X9pLT5DtiDhLVpllRdPRLiXQ7gdJtp2dtYbZ6FYKa5F9ayg4/s1600/tipo+de+demanda.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="196" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibXkTCVTTRG_-DlIJUmZ_EFi7l3PMLTeVaFGKwW3TfLouG8-zbj9vSMOCjb6nmuixIbC63SdUGxzxj7reffObPKiU5xQ5X9pLT5DtiDhLVpllRdPRLiXQ7gdJtp2dtYbZ6FYKa5F9ayg4/s400/tipo+de+demanda.jpg" width="400" /></a></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Conforme a figura acima as demandas podem variar de tipo através de 4 fatores:</div><ol start="1" style="margin-top: 0cm;" type="1"><li class="MsoNormal" style="mso-list: l1 level1 lfo1;">Tamanho (pequena, média ou grande)</li>
<li class="MsoNormal" style="mso-list: l1 level1 lfo1;">Complexidade (baixa, média ou alta)</li>
<li class="MsoNormal" style="mso-list: l1 level1 lfo1;">Classificação (corretiva, melhoria ou novidade)</li>
<li class="MsoNormal" style="mso-list: l1 level1 lfo1;">Prioridade (baixa, média ou alta)</li>
</ol><div class="MsoNormal" style="margin-left: 18.0pt;">A combinação desses valores resulta em 81 possibilidades de combinações.</div><div class="MsoNormal" style="margin-left: 18.0pt;"><br />
</div><div class="MsoNormal" style="margin-left: 18.0pt;">A análise de demandas oferece vários benefícios.</div><ol start="1" style="margin-top: 0cm;" type="1"><li class="MsoNormal" style="mso-list: l0 level1 lfo2;">Curto prazo</li>
</ol><div class="MsoNormal" style="margin-left: 36.0pt;">Auxilia no dimensionamento de recursos necessários a produção: equipamentos, mão de obra e matéria prima.</div><div class="MsoNormal" style="margin-left: 36.0pt;"><br />
</div><ol start="2" style="margin-top: 0cm;" type="1"><li class="MsoNormal" style="mso-list: l0 level1 lfo2;">Longo Prazo</li>
</ol><div class="MsoNormal" style="margin-left: 36.0pt;">Serve de base para decisões estratégicas, tais como: criação de novos produtos, ampliação da instalação.</div><div class="MsoNormal" style="margin-left: 36.0pt;"><br />
</div><div class="MsoNormal" style="margin-left: 36.0pt;"><br />
</div><div class="MsoNormal" style="margin-left: 36.0pt;"><br />
</div><div class="MsoNormal">A análise de demandas são divididas em 9 macro processos:<br />
<br />
<ul><li>Prever a demanda</li>
<li>Comunicar com o mercado</li>
<li>Influenciar a demanda</li>
<li>Prometer prazo de entrega</li>
<li>Priorizar e alocar as demandas</li>
<li>Registrar os pedidos de clientes</li>
<li>Planejar nível de serviços de clientes</li>
<li>Planejar entregas</li>
<li>Controlar os indicadores de desempenho do processo</li>
</ul></div><div class="MsoNormal" style="margin-left: 54.0pt; mso-list: l2 level1 lfo3; text-indent: -18.0pt;"><br />
</div><div class="MsoNormal">Assim podemos concluir que um sistema de gestão de demandas busca basicamente otimizar o atendimentos das solicitações de forma eficiente e transparente e controlar o fluxo das atividades desenvolvidas pelo executor.<br />
<br />
No próximo post irei discutir mais sobre a gestão de demandas. Até mais!</div>Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com0tag:blogger.com,1999:blog-1829756923885680355.post-54661493407691474072009-09-10T16:49:00.000-04:002009-09-10T16:49:42.027-04:00Versionamento de Software<div style="text-align: justify;">Versionamento de software é o processo onde atribui <b>nomes de versão</b> ou <b>números de versão</b>, sendo estes únicos, para estados de um software.<br />
<br />
Existe uma determinada categoria de números de versão (maior, menor), esses números são definidos em ordem crescente e correspondem a uma nova alteração no desenvolvimento do software. Em um nível mais detalhado, o controle de revisão é usado para rastrear o progresso das versões de uma informação eletrônica, sendo ela um software ou não.<br />
<br />
<b>Esquemas de versionamento de softwares</b><br />
<br />
Vários esquemas de numeração de versão têm sido criados para rastrear as diferentes versões de uma parte do software. Esses esquemas são usados não somente para softwares, mas também em outros contextos fora da computação.<br />
<br />
<br />
<b>Identificador baseado em sequência</b><br />
<br />
No esquema de versionamento de software baseado em sequência, a cada release do software é atribuído um identificador único que consiste em uma ou mais sequências de números e letras. Essa é o padrão, entretanto, os esquemas podem variar em várias formas tais como: na quantidade de sequências, na definição da importância com relação às diferentes sequências e na forma de incrementar as sequências.<br />
<br />
<b>Variação de importância</b><br />
<br />
Em alguns sistemas, os identificadores baseados em sequência são utilizados para repassar a importância das alterações entre os releases: As alterações são classificadas por nível de importância do release, dessa forma a decisão de qual sequência utilizar entre as liberações é baseada na importância das alterações com relação à importância da liberação anterior, onde a primeira sequência será modificada para as mudanças mais importantes, e as mudanças após a primeira sequência representam mudanças com importância menor.<br />
<br />
Por exemplo, em um esquema que se utiliza uma sequência com 4 identificadores, a primeira sequência só pode ser incrementada quando o código é totalmente reescrito, enquanto uma mudança de interface do usuário ou da documentação justifica a alteração apenas da quarta sequência.<br />
<br />
Essa prática permite aos usuários (ou usuários em potencial) avaliar em um teste real o nível da alteração que um software sofreu. Se as alterações são feitas entre, digamos 1.3rc4 e o release de produção 1.3, então com relação aquele release, podemos afirmar que teve uma produção específica para testes reais de nível qualidade e que essas alterações, de fato, não têm necessidade de serem testadas por todos os integrantes do mundo real.<br />
<br />
Esse tipo de alteração abrange normalmente o terceiro nível de numeração (“mudanças”), mas não se aplica esse nível de rigor para que as alterações recebam o número: 1.3.1, 1.3.2, 1.3.3, 1.3.4 ... 1.4b1, etc. 1.4b1, etc.<br />
<br />
Em princípio o maior número é aumentado quando há saltos significativos de funcionalidade, o menor número é incrementado apenas quando pequenas funcionalidades ou correções significativas são adicionadas e o número da revisão é incrementado quando pequenos bugs são corrigidos.<br />
<br />
Um produto típico poderia utilizar os números 0.9 (para a versão beta do software), 0.9.1, 0.9.2, 0.9.3, 1.0, 1.0.1, 1.0.2, 1.1, 1.1.1, 2.0, 2.0.1, 2.0. 2, 2.1, 2.1.1, 2.1.2, 2.2, etc. Desenvolvedores têm por vezes que saltar da versão 5.0 para a versão 5.5 para indicar que foram adicionadas funcionalidades importantes que não justificam o incremento da versão principal, que seria abusiva.<br />
<br />
Uma abordagem diferente é utilizar os maiores e menores números juntamente com uma sequência alfanumérica denotando o tipo da liberação, tais como: alfa, beta ou candidata a liberação oficial (release candidate, rc). As sucessões de liberações poderiam ser semelhantes a: 0.5, 0.6, 0.7, 0.8, 0.9, == 1.0b1, 1.0b2 (com algumas correções), 1.0b3 (com mais correções) == 1.0rc1 (caso for considerada estável) == 1.0. Se encontrar erros em 1.0rc1 que precisam ser corrigidos ele se transformará em 1.0rc2, e assim por diante. A característica importante dessa abordagem é que a primeira versão de um determinado nível (beta, rc ou release) deve ser idêntica a da última versão do release abaixo dela: você não pode realizar qualquer alteração a partir da última versão beta para primeiro RC ou a partir do último RC para a produção. Se fizer isso, deverá passar outro release para um nível inferior.<br />
<br />
No entanto, desde que as versões sejam geradas por humanos, e não por computador, não há nada que impeça alterações arbitrárias que impeçam essas regras: por exemplo, a primeira sequência poderia ser incrementada entre as versões de se diferem nem se quer por uma única linha de código, para dar uma (falsa) impressão que alterações muito significativas foram realizadas.<br />
<br />
Outros esquemas repassam importância em sequências individuais:<br />
<br />
maior.menor [. Build [. revision]] ou major.minor[.maintenance[.build]].<br />
<br />
Mais uma vez, neste exemplo, o que constitui uma alteração importante de uma alteração menos importante é totalmente arbitrária e é o autor que define o que é uma build, ou como uma revisão (revision) se difere de uma pequena alteração.<br />
Na maioria dos softwares proprietários, a primeira versão liberada de um produto é a versão 1.<br />
<br />
<b>Definindo estágio de desenvolvimento</b><br />
<br />
Alguns esquemas utilizam fazem uso de um zero na primeira sequência para designar os status de liberação alfa ou beta, onde não são totalmente estáveis para uso geral, práticas de implantação, e são destinados para testes ou uso interno.<br />
<br />
Pode ser usado na terceira posição:<br />
<br />
• 0 para o estado alfa<br />
• 1 para o estado beta<br />
• 2 para candidato a liberação (release candidate)<br />
• 3 para a liberação pública (public release).<br />
<br />
Por exemplo:<br />
<br />
• 1.2.0.1 ao invés de 1.2-a<br />
• 1.2.1.2 ao invés de 1.2-b2 (beta com alguns bugs corrigidos)<br />
• 1.2.2.3 ao invés de 1.2-rc<br />
• 1.2.3.0 ao invés de 1.2-r (distribuição comercial)<br />
• 1.2.3.5 ao invés de 1.2-r5 (distribuição comercial com correção de vários bugs)<br />
<br />
<b>Separando sequências</b><br />
<br />
Quando impressas, as sequências podem ser separadas com caracteres. A escolha dos caracteres e sua utilização variam de acordo com o esquema. A lista seguinte exibe exemplos hipotéticos que esquemas de separação para a mesma liberação (release) (O 13º do terceiro nível da revisão para o 4º do segundo nível da revisão para o 2º do primeiro nível da revisão):<br />
<br />
• Um esquema pode usar o mesmo caractere para todas as sequências: 2.4.13, 2/4/13, 2-4-13<br />
• A escolha do esquema de sequência de separações pode ser inconsistente, separando algumas sequências e outras não: 2.413<br />
• A escolha do esquema de caracteres pode ser inconsistente dentro de um mesmo identificador 2.4_13<br />
<br />
Quando um ponto é usado para separar as sequências, ele não pode ser representado como um ponto decimal, e as sequências não têm posição significativa. Um identificador 2.5, por exemplo, não é “2 e meio” ou “metade da versão 3”, é o 5º do segundo nível da revisão do 2º do primeiro nível da revisão e não seria adequando ao menos que existisse um 2.1, 2.2, 2.3 e 2.4.<br />
<br />
<b>Número de sequências</b></div><div style="text-align: justify;"><br />
Existem às vezes 4 números não publicados que indicam a build do software (utilizado pela Microsoft). Algumas empresas incluem ainda a data de realização da build. Versões numeradas podem conter letras e outros caracteres, por exemplo, Lotus 1-2-3 Release 1a.<br />
<br />
<b>Incrementando sequências</b><br />
<br />
Existem duas escolas de pensamento de como os números da versão são incrementados: Muitos pacotes de software livre tratam os números da versão como um fluxo contínuo, pois um software livre pode ter números de versão 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.10.0, 1.11.0, 1.11.1, 1.11.2, etc. Um exemplo é o pacote de software do MediaWiki. No entanto, muitos programas tratam o número de versão de outro modo, eles podem ter números de versão como: 1.8, 1.9, 1.9.1, 1.9.2, etc. Nos pacotes de software que utilizam essa forma de numeração 1.91 é a próxima menor versão depois de 1.9. Releases de manutenção, isto é, correções de bugs, geralmente seriam denominadas como: 1.91a, 1.91b, etc.<br />
<br />
<b>Utilizando números negativos</b><br />
<br />
Existem alguns projetos que usam números negativos na versão. Um exemplo é o compilador Smalleiffel que começou a partir de -1.0 e contadas de 0.0 em diante.<br />
<br />
<b>Grau de compatibilidade</b><br />
<br />
Alguns projetos utilizam o número maior da versão para indicar releases incompatíveis. Dois exemplos são: Apache TAEG e do FarCry CMS.<br />
<br />
<b>Data</b><br />
<br />
O projeto Wine utilizou um esquema de versionamento baseado em datas, nos utiliza o ano, seguido do mês, seguido do dia do lançamento, por exemplo, “Wine 20040505”. O Wine segue atualmente um padrão de liberação por faixa, a versão mais atual a partir de 6 de Junho de 2008 é 1.0-rc4. O Linux Unbutu utiliza um esquema semelhante, Unbutu 8.10, por exemplo, foi liberado em Outubro de 2008.<br />
<br />
Ao utilizar datas em versões, por exemplo, nome de arquivo, é comum utilizar o esquema ISO YYYY-MM-DD, pois essa string é facilmente ordenada em ordem crescente e decrescente. Os hífens são geralmente omitidos.<br />
<br />
<b>Ano de lançamento</b><br />
<br />
Outros exemplos, identificando versões por ano (Adobe Illusrator 88, Word Perfect Office 2003). Embora quando a data é utilizada para identificar a versão é geralmente para fins de marketing e existe um numero de versão real. Por exemplo, o Microsoft Windows 2000 Server é versionado internamente como NT 5.0. (“NT” é uma referência para o nome original do produto). <br />
<br />
<b>Códigos Alfanuméricos</b><br />
<br />
Exemplos:<br />
<br />
• Macromedia Flash MX<br />
• Adobe Photoshop CS2</div>Anonymoushttp://www.blogger.com/profile/03668534647040817395noreply@blogger.com2