<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.caelum.com.br &#187; agilidade</title>
	<atom:link href="http://blog.caelum.com.br/tag/agilidade/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.caelum.com.br</link>
	<description>blog dos desenvolvedores da Caelum</description>
	<lastBuildDate>Thu, 09 Feb 2012 13:04:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>TDD e sua influência no acoplamento e coesão</title>
		<link>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/</link>
		<comments>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 15:14:13 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[Inovação]]></category>
		<category><![CDATA[acoplamento]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[coesão]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design evolutivo]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testes de unidade]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=4116</guid>
		<description><![CDATA[Escrever testes de unidade é uma prática cada vez mais adotada. Ela ajuda a verificar se tudo funciona como o esperado mesmo após mudanças, trazendo mais segurança para a equipe ao alterar o código. Mas os testes de unidade vão além, possibilitando a validação de um design. Um código fácil de testar tende a apresentar um bom design. <a href="http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/#more-4116'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd.jpg" width="240" />
		</p><p>Escrever testes de unidade é uma prática cada vez mais adotada. Ela  ajuda a verificar se tudo funciona como o esperado mesmo após mudanças, trazendo mais segurança para a equipe ao alterar o código. Mas os testes de unidade vão além, <strong>possibilitando a validação de um design</strong>.</p>
<p><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd.jpg"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2011/02/tdd-300x186.jpg" alt="" title="tdd" width="300" height="186" class="aligncenter size-medium wp-image-4120" /></a></p>
<p>Um código fácil de testar tende a apresentar um bom design. <em><a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2007/09/the-deep-synerg.html">Existe uma grande sinergia entre testabilidade e um bom design</a></em>. Isso acontece pois, para que o programador consiga testar uma classe de maneira isolada e facilmente, essa classe deve lidar muito bem com suas dependências (buscando sempre um baixo acoplamento) e possuir pouca responsabilidade (ou seja, ser altamente coesa). Caso contrário, o programador gastará muito tempo tentando testá-la, um possível indicador de que a classe apresenta um design pobre.</p>
<p>Um design que apresenta classes com alto acoplamento são difíceis de testar, surgindo a necessidade de passar as dependências para nossos objetos e só então testá-los.</p>
<p>O primeiro resultado ao adicionar testes de unidade a um sistema é a mudança de padrões imperativos de execução onde instanciamos objetos e invocamos métodos para a injeção de dependências.</p>
<p>O exemplo a seguir mostra um processador sendo instanciado, o que torna difícil verificar se o comportamento do <code>ExecutorDeBatch </code> foi correto sem executar o código da classe <code>Processador</code>:</p>
<pre class="brush: java; title: ; notranslate">
public class ExecutorDeBatch {
  public void le(ListaDeItens itens) {
    Processador processador = new Processador();
    while(itens.temProximo()) {
       String item = sc.proximo();
       processador.interpreta(item);
    }
  }
}
</pre>
<p>O teste acima verifica o comportamento do <code>ExecutorDeBatch</code> junto com o <code>Processador</code>. Esse tipo de teste é considerado de integração, não passando muita informação sobre o acoplamento entre as classes, mas somente garantindo o comportamento em conjunto. </p>
<p>Para isolar a classe acima seria necessário a utilização de um <a href="http://blog.caelum.com.br/testes-unitarios-com-jmock-2/">mock</a> no lugar do <code>Processador</code>. Da maneira que o código está, seria bastante trabalhoso. No Java exigiria até manipulação de bytecode durante o classload para que fosse possível alterar a classe instanciada no momento do <code>new Processador()</code> por exemplo. Para isso, o programador deve deixar essas dependências bem explícitas, recebendo-as através do construtor, por exemplo. Teríamos então o seguinte código:</p>
<pre class="brush: java; title: ; notranslate">
public class ExecutorDeBatch {
  private Processador processador;
  public ExecutorDeBatch(Processador processador) {
    this.processador = processador;
  }

  public void le(ListaDeItens itens) {
    while(itens.temProximo()) {
       String item = sc.proximo();
       processador.interpreta(item);
    }
  }
}
</pre>
<p>Passar um mock para a classe acima e consequentemente testá-la de maneira isolada ficou é fácil. A adoção dos testes de unidade deixa explícito o excesso de  dependências (ou dependências implícitas escondidas). </p>
<p>Por fim, os testes precisam ser simples e curtos, limitando seu escopo; um teste muito grande ou complicado <a href="http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627">pode indicar que o método em questão possui muita responsabilidade</a>.</p>
<p>Considere uma classe que é responsável por gerar uma nota fiscal a partir de uma fatura e disparar a mesma para o e-mail do cliente, assim como para um sistema SAP qualquer. Essa classe já possui as dependências bem explícitas:</p>
<pre class="brush: java; title: ; notranslate">
public class GeradorDeNotaFiscal {
       private final Sap sap;
       private final EnviadorDeEmails enviador;

       public GeradorDeNotaFiscal(Sap sap, EnviadorDeEmails enviador) {
               this.sap = sap;
               this.enviador = enviador;
       }

       private NotaFiscal geraNotaFiscalAPartirDa(Fatura fatura) {
           // codigo de geracao da nota fiscal
       }

       public void gera(Fatura fatura) {
               NotaFiscal nf = geraNotaFiscalAPartirDa(fatura);

               sap.armazena(nf);
               enviador.envia(nf);
       }
}
</pre>
<p>Passar mocks para essa classe é fácil, já que é possível injetar todas as dependências nela. O problema é que, para criar testes para ela, o programador se preocuparia em testar se a nota fiscal foi gerada, se ela é enviada ao SAP e se ela é enviada para o cliente:</p>
<pre class="brush: java; title: ; notranslate">
@Test public void deveGerarANf() { ... }
@Test public void deveArmazenarNfNoSap() { ... }
@Test public void deveEnviarNfParaOEmailDoCliente() { ... }
</pre>
<p>Perceba que essa classe tem responsabilidades demais: ela gera NF, envia para o SAP, envia para o cliente. Ao escrever esses testes, o programador perceberia que, em cada teste, ele estaria preocupado em testar uma responsabilidade da classe, sem se importar com a outra. No teste <code>deveArmazenarNfNoSap</code>, por exemplo, o programador seria obrigado a passar um stub da classe <code>Email</code>, mesmo não sendo o foco daquele teste. Isso torna a escrita do teste mais massante é um sinal de que a classe tem baixa coesão.</p>
<p>Portanto, se o seu design possue um alto acoplamento ou uma baixa coesão, será praticamente impossível escrever testes de unidade. Por esse mesmo motivo métodos estáticos, singletons, factories e estado global dificultam os testes de unidade.</p>
<p>Pensar e criar os testes antes do código também auxiliam no design. Usar <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530">Test-Driven Development</a> força que a concentração do pensamento lógico foque nas responsabilidades de cada método, ao invés da exata implementação do mesmo.</p>
<p>Esse impacto no design é tão grande que muitos <a href="http://www.agiledata.org/essays/tdd.html">vão utilizar a sigla TDD para Test-Driven Design</a>. Com TDD o programador é forçado a pensar em decisões de design antes do código de implementação, criando um maior desacoplamento, <a href="http://athenea.ort.edu.uy/publicaciones/ingsoft/recursos/articulos/AimFire.pdf">deixando mais claro suas necessidades</a>.</p>
<p>O TDD, através dos testes de unidade e refatoração, possibilitam que o <a href="http://martinfowler.com/articles/designDead.html">design apareça de uma maneira mais evolutiva</a>, mas sem mágicas, sempre dependendo de conhecimento do desenvolvedor em relação a design e orientação a objetos.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/tdd-e-sua-influencia-no-acoplamento-e-coesao/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Perdendo ou ganhando tempo com testes de unidade</title>
		<link>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/</link>
		<comments>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 15:06:22 +0000</pubDate>
		<dc:creator>Mauricio Aniche</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[acoplamento]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[ioc]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[pm-87]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[teste]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3588</guid>
		<description><![CDATA[Durante as aulas e palestras sobre TDD e testes de software é bem comum ouvir perguntas relativas a &#8220;o que deve ser testado e o que não precisa ser testado&#8221;. Geralmente os exemplos inicials que encontramos na literatura sobre TDD são muito simplistas, nos levando a crer que devemos testar todo e qualquer método de <a href="http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/#more-3588'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.caelum.com.br/curso/pm-87-agile-praticas-ageis/">Durante as aulas e palestras sobre TDD e testes de software</a> é bem comum ouvir perguntas relativas a &#8220;o que deve ser testado e o que não precisa ser testado&#8221;.  Geralmente os exemplos inicials  que encontramos na literatura sobre TDD são muito simplistas, nos levando a crer que devemos testar todo e qualquer método de uma classe de maneira isolada, mesmo que não faça muito sentido.</p>
<p>Um exemplo desse tipo de abordagem é a tentativa de se testar uma constante, entre outros clássicos como a presença de uma anotação, métodos de delegação, getters e setters, etc. Supondo uma classe que armazena constantes de cartão de crédito e um possível teste de unidade para ela:</p>
<pre class="brush: java; title: ; notranslate">
public class CartoesDeCreditoTest {
  @Test
  public void deveRelacionarVisaComOValor123() {
    assertEquals(123, CartoesDeCredito.VISA);
  }
}

public class CartoesDeCredito {
  public final static int VISA = 123;
  public final static int MASTERCARD = 456;
}
</pre>
<p>Repare que existe uma duplicação de dados entre o código de teste e o código de produção: o número <em>123</em>. Quando o valor dessa constante mudar, você possui dois pontos de código para alterar. Ao fazer uma refatoração para remover essa duplicação, teremos um resultado como a seguir:</p>
<pre class="brush: java; title: ; notranslate">
public class CartoesDeCreditoTest {
  @Test
  public void deveRelacionarVisaComOValor123() {
    assertEquals(CartoesDeCredito.VISA, CartoesDeCredito.VISA);
  }
}
</pre>
<p>Muitas vezes, o programador, acostumado a escrever testes de unidade para todo o código, acaba desenvolvendo testes sem utilidade: código que na realidade não testa nada. Naturalmente, o desenvolvedor não faria a refatoração acima, tal exemplo demonstra como um teste do genêro não traz valor, somente complexidade para nosso sistema.</p>
<p>Ou seja, em casos como o mostrado acima não há utilidade em escrever um teste de unidade para constantes. Ao fazer isso, o programador gera <a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530/ref=sr_1_1?ie=UTF8&amp;qid=1290727199&amp;sr=8-1">duplicação de dados entre a classe de teste e a de produção</a>.</p>
<p>É importante testar constantes, mas no caso acima por exemplo, <strong>não através de testes de unidade</strong>: se ela representa um valor de um outro sistema, por exemplo, escreva um teste de integração.</p>
<p>No caso do cartão de crédito, suponha que a constante 123 seja o código do pagamento via cartão VISA no sistema do PayPal, portanto testamos a integração entre a aplicação e o sistema externo. Verifique se, ao passar o valor 123, o pagamento gerado foi um pagamento VISA.</p>
<pre class="brush: java; title: ; notranslate">
@Test
public void deveEnviarCartaoVisaParaOPayPal() {
  Cobranca resultado = payPal.efetuaCobranca(valor, numeroDeUmCartaoVisa, CartoesDeCredito.VISA);

  assert(that(resultado.getStatus()).is(PayPal.APROVADO));
}
</pre>
<p>Em um exemplo mais elaborado, imagine agora o seguinte trecho de código abaixo que usa o Active Record do Rails para fazer um filtro:</p>
<pre class="brush: ruby; title: ; notranslate">
def filtro(name)
  where(&quot;nome like %#{name}%&quot;)
end

def test_verifica_se_where_foi_invocado
  componente.should_receive(:where).with(&quot;nome like 'guilherme'&quot;)
  componente.filtro(&quot;guilherme&quot;)
end

# outra variação do mesmo teste:

def test_verifica_se_where_foi_invocado
  query = componente.filtro(&quot;guilherme&quot;)
  query[0].should == &quot;nome like 'guilherme'&quot;
end
</pre>
<p>Neste caso, uma vez que o método possui um corpo simples, uma invocação de uma função do Active Record, o teste abusa de <em>mocks</em> e é apenas uma mímica daquilo que o método executou. <strong>Ele garante somente que o programador digitou aquilo que ele esperava digitar.</strong> Testes como esse só indicam um problema no design do teste ou um problema no design do código.</p>
<p>No mundo Java é comum ver similares quando encontramos a utilização de Mocks ao extremo:</p>
<pre class="brush: java; title: ; notranslate">
public void adiciona(Produto p) {
  this.session.save(p);
}

@Test
public void testSalvarEhInvocado() {
  Produto produto = new Produt();
  one(session).save(produto);
  dao.adiciona(produto);
}
</pre>
<p>Veja que o próprio nome do método diz que ele não serve pra nada: <em>verifica se o salvar é invocado</em>. Você quer testar o comportamento que essa classe terá sobre seu sistema e não se um determinado método foi invocado. A obviedade que o método está sendo invocado é trivial de ser notada e por isso mesmo não precisaria ser nosso foco no teste.</p>
<p>Mas alguns podem dizer: <em>mas não preciso testar o Active Record, eu sei que ele funciona</em>. Ou ainda, <em>não preciso testar o Hibernate, eu sei que ele funciona</em>. Sim, você não precisa testar o Active Record unitariamente pois ele já foi testado, <strong>mas existe a necessidade de testar a integração do seu código com o Active Record.</strong> No exemplo de uma query, sabemos que escrevemos uma query como desejávamos, mas ela está retornando aquilo que desejamos? E deixando de lado o resto? São essas perguntas que nosso teste precisa responder.</p>
<pre class="brush: ruby; title: ; notranslate">
def test_deve_retornar_pessoas_que_tenham_parte_do_nome
  lista = executa_metodo_where(&quot;joão&quot;);

  lista.should_contain o_cidadao(&quot;João Gilberto&quot;)
end
</pre>
<p>O mesmo vale para queries em Java que utiliza JPA/Hibernate.</p>
<p><strong>Para saber mais sobre teste e design:</strong> Kent Beck já discutia acoplamento tanto de dados quanto de código entre classes de teste e classes de produção. Isso é muitas vezes ignorado pelo programador. Imagine que você precise alterar muitos testes toda vez que fizer uma pequena alteração: é um indício de um <a href="http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">design rígido</a>, onde uma simples alteração propaga uma série de outras alterações.</p>
<blockquote><p>Como regra geral, que possui suas excecões, não existe valor em um teste que é uma mímica daquilo que foi <strong>digitado</strong> e não de seus efeitos e retornos. Nesse caso, pense duas vezes antes de escrever esse teste e verifique se testar aquela classe de outra maneira (através de um teste de integração, por exemplo) não seria mais útil.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/perdendo-ou-ganhando-tempo-com-testes-de-unidade/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Mudanças simples x Soluções simples</title>
		<link>http://blog.caelum.com.br/mudancas-simples-x-solucoes-simples/</link>
		<comments>http://blog.caelum.com.br/mudancas-simples-x-solucoes-simples/#comments</comments>
		<pubDate>Thu, 18 Nov 2010 20:29:11 +0000</pubDate>
		<dc:creator>Mauricio Aniche</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Arquitetura]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[Qualidade]]></category>
		<category><![CDATA[refatoração]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[xp]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3445</guid>
		<description><![CDATA[O processo de entrega de uma funcionalidade nova envolve implementar ou corrigir algo que o nosso sistema atualmente não comporta. Dados os problemas que o programa resolve nesse instante, existem diversas maneiras distintas de resolvê-los, todas válidas, algumas mais limpas e mais simples do que outras. O gráfico a seguir mostra uma situação onde nosso <a href="http://blog.caelum.com.br/mudancas-simples-x-solucoes-simples/#more-3445'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-3.png" width="240" />
		</p><p>O processo de entrega de uma funcionalidade nova envolve implementar ou corrigir algo que o nosso sistema atualmente não comporta. Dados os problemas que o programa resolve nesse instante, existem diversas maneiras distintas de resolvê-los, todas válidas, algumas mais limpas e mais simples do que outras.</p>
<p>O gráfico a seguir mostra uma situação onde nosso programa não resolve o problema atual que desejamos atacar, onde:</p>
<p>a) <span style="color: #ff0000"><strong>vermelho</strong></span>: representa variações do sistema que não resolveriam meu problema;<br />
b) <span style="color: #ffcc00"><strong><span style="color: #95971f">amarelo</span></strong></span>: minha situação atual;<br />
c) <span style="color: #008000"><strong>verde</strong></span>: soluções possíveis.</p>
<div id="attachment_3453" class="wp-caption aligncenter" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/1.png"><img class="size-medium wp-image-3453" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/1-300x251.png" alt="Soluções possiveis para um problema" width="300" height="251" /></a><p class="wp-caption-text">Soluções possiveis para um problema</p></div>
<p>Mas dentro das soluções possíveis, existem aquelas <strong>mudanças que são simples</strong> de serem executadas, por exemplo incluir um &#8220;if&#8221; ou simplesmente fazer um copy e paste de código, um pequeno passo, uma mudança simples, um <em>baby step</em>. <strong>Mudanças simples que resolvem o problema</strong>, representadas em verde escuro aqui:</p>
<div id="attachment_3454" class="wp-caption aligncenter" style="width: 289px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/2.png"><img class="size-full wp-image-3454" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/2.png" alt="Mudanças simples" width="279" height="235" /></a><p class="wp-caption-text">Mudanças simples</p></div>
<p>Por fim, existem as soluções mais simples para o problema. A solução mais simples pode ser extrair uma classe ou utilizar uma biblioteca que executa a lógica para nós, por exemplo. No diagrama a seguir as soluções mais simples são representadas em azul:</p>
<div id="attachment_3455" class="wp-caption aligncenter" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/3.png"><img class="size-medium wp-image-3455" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/3-300x252.png" alt="Soluções simples" width="300" height="252" /></a><p class="wp-caption-text">Soluções simples</p></div>
<p>A execução desses passos, <em>baby steps</em>, traz o código para dentro das mudanças simples que resolvem o problema. Mas a sequência dos mesmos pode nos levar para diversos lugares diferentes: alguns mais próximos das soluções mais simples, <a href="http://www.aniche.com.br/2010/11/voce-quer-testar-metodos-privados-certeza/">outros cada vez mais distantes das mesmas, nos deixando com um débito técnico cada vez maior</a>.</p>
<p>Pior ainda, a adoção cega de <em>baby steps</em> ou de mudanças simples sem nenhuma prática para garantir a qualidade pode levar a uma situação onde seja impossível chegar em uma solução simples: seu sistema vira uma <a href="http://en.wikipedia.org/wiki/Big_ball_of_mud" target="_blank">grande bola de lama</a>.</p>
<p>Essa situação é o inferno de qualquer sistema: passos simples não são mais capazes de <a href="http://en.wikipedia.org/wiki/KISS_principle" target="_blank">manter as coisas simples</a>.</p>
<div id="attachment_3458" class="wp-caption aligncenter" style="width: 270px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo.png"><img class="size-large wp-image-3458" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-389x1024.png" alt="Uso puro de baby steps" width="260" height="682" /></a><p class="wp-caption-text">Uso puro de baby steps não implica em melhoria de qualidade. Passos muito simples podem levar seu sistema a situações negativas.</p></div>
<p>Em algumas situações, o <em>baby step</em> pode implicar em uma das melhores soluções, mas para isso é necessário o domínio da tecnologia, do negócio, design e linguagem, algo que nem sempre é a realidade do desenvolvedor quando escreve uma funcionalidade:</p>
<div id="attachment_3463" class="wp-caption aligncenter" style="width: 522px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-3.png"><img class="size-full wp-image-3463" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-3.png" alt="Baby step e design" width="512" height="215" /></a><p class="wp-caption-text">Baby step de um desenvolvedor com domínio forte da tecnologia, linguagem, domínio de negócio e sistema.</p></div>
<p>Como é difícil executar um passo-a-passo muito suave e chegar em uma solução simples qualquer, adicionamos mais uma técnica ao processo: além de executar as tarefas em pedaços pequenos (mas não mínimos), refatoramos nosso código, para simplificá-lo.</p>
<p>Cada passo de simplificação através da refatoração coloca nosso código mais próximo do sistema ideal: o mais simples de todos que resolve nossos problemas.</p>
<div id="attachment_3462" class="wp-caption aligncenter" style="width: 522px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-2.png"><img class="size-large wp-image-3462" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/11/Diagramalindo-2-1024x853.png" alt="Refatorando" width="512" height="426" /></a><p class="wp-caption-text">A refatoração que a cada passo simplifica o código nos leva cada vez mais próximos a melhor solução para nossos problemas.</p></div>
<p><a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672">Com a refatoração contínua</a>, cada passo que damos ao implementar uma nova feature nos mantém ainda próximos das soluções simples.</p>
<p>Mais importante do que fazer passos minúsculos (<em>baby steps</em>) é fazer passos que fazem sentido para levá-lo em direção a melhor solução (e não somente a mudança mais simples). Para isso não podemos nos esquecer de refatorar. E não só refatorações de baixo nível (como renomear variáveis, mover métodos, etc), mas sim refatorações de alto nível (como abstrair comportamentos).</p>
<p>Imagine o seguinte trecho de código, responsável por calcular o salário de um funcionário. Dependendo do cargo do funcionário, o algoritmo para o cálculo é diferente.</p>
<pre class="brush: java; title: ; notranslate">
public class CalculoDeSalario {

  public CalculoDeSalario(RegrasFiscais regrasFiscais, ...) {
    // ...
  }

  public double calcula(Funcionario f) {
    if(f.getCargo() == Cargo.VENDEDOR) {
      // calcula salario do vendedor usando regras fiscais, etc
    }

    if(f.getCargo() == Cargo.GERENTE) {
      // calcula salario do gerente usando regras fiscais, etc
    }
  }
}
</pre>
<p>Agora suponha que um novo cargo apareceu na empresa e precisamos calcular o salário das pessoas que farão o trabalho desse novo cargo. O código mais simples que faria isso acontecer, seria:</p>
<pre class="brush: java; title: ; notranslate">
public class CalculoDeSalario {

  public CalculoDeSalario(RegrasFiscais regrasFiscais, ...) {
    // ...
  }

  public double calcula(Funcionario f) {
    if(f.getCargo() == Cargo.VENDEDOR) {
      // calcula salario do vendedor usando regras fiscais, etc
    }

    if(f.getCargo() == Cargo.GERENTE) {
      // calcula salario do gerente usando regras fiscais, etc
    }

    if(f.getCargo() == Cargo.MARKETING) {
      // calcula salario do marketing usando regras fiscais, etc
    }
  }
}
</pre>
<p>Mas essa não é a melhor solução que resolveria o problema. A cada novo <em>if</em> inserido nesse código, mais longe estamos da melhor solução. O design fica cada vez mais rígido. E pior: refatorar esse trecho de código fica cada vez mais difícil: até mesmo o segundo if que foi adicionado ao código já havia o afastado da melhor solução!</p>
<p>Ao implementar uma nova funcionalidade, o programador <a href="http://www.agiledata.org/essays/tdd.html" target="_blank">deve observar o design atual da sua aplicação</a>. Se o design atual já provê uma maneira fácil de implementar a funcionalidade, então vá em frente. Caso contrário, o programador deve <strong>refatorar o design para permitir que você possa adicionar essa funcionalidade da maneira mais simples possível</strong>.</p>
<p>No exemplo acima, uma solução seria criar uma estratégia (do padrão de projeto Strategy) para calcular o salário de acordo com o cargo. Cada cargo seria responsável por devolver o seu algoritmo de cálculo. Por exemplo:</p>
<pre class="brush: java; title: ; notranslate">
public class CalculoDeSalario {

  public CalculoDeSalario(RegrasFiscais regrasFiscais, ...) {
    // ...
  }

  public double calcula(Funcionario f) {
    AlgoritmoDeCalculoDeSalario calculadora = f.getCargo().getAlgoritmoDeCalculo(regrasFiscais);
    return calculadora.calcula();
  }
}
</pre>
<p>Se essa é a melhor solução, é difícil dizer. Mas com certeza ela é uma solução melhor do que as anteriores. Mas, veja que após essa refatoração, implementar o cálculo de salário para o novo cargo é muito mais fácil. Agora posso voltar aos meus <em>baby steps</em>, já que a implementação corrente está em um lugar seguro.</p>
<p>Toda essa experiência se resume a uma frase que surgiu em uma conversa entre Guilherme Silveira e Maurício Aniche:</p>
<blockquote><p>A mudança mais simples para resolver um problema não é necessariamente a solução mais simples para resolvê-lo.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/mudancas-simples-x-solucoes-simples/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Prática: Evite influenciar estimativas: estime até mesmo as histórias mais simples</title>
		<link>http://blog.caelum.com.br/pratica-evite-influenciar-estimativas-estime-ate-mesmo-as-historias-mais-simples/</link>
		<comments>http://blog.caelum.com.br/pratica-evite-influenciar-estimativas-estime-ate-mesmo-as-historias-mais-simples/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 12:33:38 +0000</pubDate>
		<dc:creator>Mauricio Aniche</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[desenvolvedor]]></category>
		<category><![CDATA[estimativa]]></category>
		<category><![CDATA[planning poker]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3402</guid>
		<description><![CDATA[Sintoma: Durante a estimativa de estórias do backlog, ao aparecer uma estória razoavelmente clara ou simples, um desenvolvedor (geralmente mais experiente) toma a palavra antes de estimar: &#8220;Essa história tem 3 pontos. Pode ser? Todo mundo concorda, não é?&#8221; Problema: Ao fazer isso, o desenvolvedor acaba enviesando a estimativa dessa estória. Frases como essa durante <a href="http://blog.caelum.com.br/pratica-evite-influenciar-estimativas-estime-ate-mesmo-as-historias-mais-simples/#more-3402'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p><strong>Sintoma:</strong> <a href="http://www.amazon.com/Agile-Estimating-Planning-Mike-Cohn/dp/0131479415">Durante a estimativa de estórias do backlog</a>, ao aparecer uma estória razoavelmente clara ou simples, um<br />
desenvolvedor (geralmente mais experiente) toma a palavra antes de estimar: <em>&#8220;Essa história tem 3 pontos. Pode ser? Todo mundo concorda, não é?&#8221;</em></p>
<p><strong>Problema: </strong>Ao fazer isso, o desenvolvedor acaba enviesando a estimativa dessa estória. Frases como essa durante a estimativa inibem os outros desenvolvedores e fazem com que eles escondam a sua opinião (<em>pois, se o desenvolvedor experiente tem tanta certeza que a estória tem 3 pontos, ele deve estar certo, e eu devo estar errado; o <strong>problema</strong> que eu havia imaginado não deve existir&#8230;</em>).</p>
<p><strong>Solução: </strong><a href="http://www.planningpoker.com/references.html#ref2">A estimativa acontece em grupo</a> justamente para tentar diminuir o seu possível erro. Além disso, <a href="http://www.slideshare.net/jssunil/agile-software-estimation">estimar em grupo ajuda a levantar melhor os possíveis problemas que a equipe irá passar durante a implementação da estória</a>, afinal nesse momento temos uma equipe inteira pensando, e não só apenas uma pessoa.</p>
<p>Não só o desenvolvedor mas também o Product Owner (ou clientes dependendo de sua abordagem e metodologia) costuma utilizar palavras como &#8220;fácil&#8221; ou &#8220;simples&#8221; para descrever uma história. Qualquer tipo de adjetivo do gênero pode trazer um peso decisivo na hora de julgar a dificuldade da estória. <a href="http://www.caelum.com.br/curso/pm-83-agile-scrum/">Durante os treinamentos de Scrum e Lean</a>, no momento de explicar uma história, adjetivos surgem a todo instante por parte do PO.</p>
<p>Todos os participantes mostram suas estimativas juntos, justamente para que um desenvolvedor não influencie na opinião do outro, e as ideias possam surgir mais livremente e serem discutidas. Mesmo o desenvolvedor iniciante pode ver problemas ou soluções que um desenvolvedor mais experiente não enxergou. Mas, por saber que ele é iniciante, ele é mais facilmente influenciado pelos experientes!</p>
<p>Portanto, por mais simples e clara que a história possa parecer para você, faça o <em>planning poker</em> (ou qualquer <a href="http://www.amazon.com/Agile-Estimating-Planning-Mike-Cohn/dp/0131479415">outra técnica para estimar</a>) da maneira correta. Estime junto com o time. Deixe a estimativa <strong>emergir</strong> do time todo. Se o objetivo da estória estiver realmente claro, o time não vai levar muito tempo para chegar em um acordo sobre a estimativa.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/pratica-evite-influenciar-estimativas-estime-ate-mesmo-as-historias-mais-simples/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Seu cliente precisa saber o andamento do projeto</title>
		<link>http://blog.caelum.com.br/seu-cliente-precisa-saber-o-andamento-do-projeto/</link>
		<comments>http://blog.caelum.com.br/seu-cliente-precisa-saber-o-andamento-do-projeto/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 16:06:12 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[burndown]]></category>
		<category><![CDATA[métricas]]></category>
		<category><![CDATA[pm-83]]></category>
		<category><![CDATA[pm-87]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=3335</guid>
		<description><![CDATA[Sintoma: no dia a dia o cliente envia emails perguntando a situação de determinada história e o andamento do projeto completo. Os desenvolvedores tem grande parte de seu tempo diário consumido para fazer um relatório de situação, ao invés de focarem em seu trabalho principal, o desenvolvimento. Ação: como cliente sempre surge um desejo natural <a href="http://blog.caelum.com.br/seu-cliente-precisa-saber-o-andamento-do-projeto/#more-3335'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/c1.png" width="240" />
		</p><p><b>Sintoma</b>: <a href="http://blog.caelum.com.br/pratica-agil-facilite-a-comunicacao-interna/">no dia a dia o cliente envia emails</a> perguntando a situação de determinada história e o andamento do projeto completo. Os desenvolvedores tem grande parte de seu tempo diário consumido para fazer um relatório de situação, ao invés de focarem em seu trabalho principal, o desenvolvimento.</p>
<p><b>Ação</b>: como cliente sempre surge um desejo natural de <a href="http://www.scrumalliance.org/articles/140">entender a situação atual</a> do que foi contratado: <a href="http://www.projectsmart.co.uk/the-curious-case-of-the-chaos-report-2009.html">desejamos ter uma previsibilidade do que irá acontecer a curto prazo, mesmo que imprecisa</a>.</p>
<p>Ao contratarmos um serviço de reforma, desejamos saber se o encanamento está pronto para que passemos a execução da pintura da parede. Se algum problema mais grave ocorrer, é importante que o cliente saiba logo para não ser pego de surpresa quando do atraso do projeto.</p>
<p>Em todos os cenários, é importante para o cliente conhecer o andamento do projeto para que, quando o mesmo não esteja andando, isto é, um impedimento esteja presente, possa ajudar a resolver o problema de alguma forma.</p>
<p>Tudo isso acelera o ciclo de feedback da situação do projeto para o cliente e um dos recursos mais comuns para isso é <a href="http://en.wikipedia.org/wiki/Burn_down_chart">o uso do gráfico de Burndown</a>. Nele plotamos os pontos a serem desenvolvidos na iteração atual, e decrescemos o mesmo a medida que as histórias são aprovadas de acordo com o conceito de pronto.</p>
<div id="attachment_3338" class="wp-caption alignnone" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/a1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/a1-300x172.png" alt="" title="atual" width="300" height="172" class="size-medium wp-image-3338" /></a><p class="wp-caption-text">Na iteração atual desenhamos a linha média de acordo com a velocidade esperada. Enquanto estivermos acima da média.</p></div>
<p>Da mesma maneira, no lado positivo, caso o andamento seja melhor do que o esperado, o cliente pode rapidamente se preparar para dar novas informações sobre o que será feito durante o tempo livre nessa iteração.</p>
<div id="attachment_3339" class="wp-caption alignnone" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/b1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/b1-300x166.png" alt="" title="aprovando" width="300" height="166" class="size-medium wp-image-3339" /></a><p class="wp-caption-text">Em uma iteração comum, o início da aprovação demora um pouco pois as histórias tem que ser terminadas e a partir de então os pontos são entregues.</p></div>
<p>Por fim, o gráfico pode indicar diversos impedimentos e basta bater o olho para perceber algum tipo de problema. O que há de estranho na iteração a seguir?</p>
<div id="attachment_3340" class="wp-caption alignnone" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/c1.png"><img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/10/c1-300x166.png" alt="" title="aguardando" width="300" height="166" class="size-medium wp-image-3340" /></a><p class="wp-caption-text">Nesse exemplo, as histórias finalizadas demoram para ser aprovadas: repare a barra horizontal onde as histórias podem estar terminadas aguardando aprovação.</p></div>
<p>A barra horizontal indica um momento de pausa na entrega, que estava indo bem até então: diversos fatores podem causar essa pausa. No caso dessa equipe e iteração, podemos verificar em um outro gráfico que as histórias eram entregues mas o tempo para aprovação era longo.</p>
<p>O perigo dessa pausa é chegar muito próximo ao fim da iteração e a entrega ser sempre parcial, nunca completa pois após a avaliação ser feita não há mais tempo na iteração para fazer as correções devidas.</p>
<p>Outro motivo comum para uma linha parada é a história não ser aprovada por falta de compreensão no momento da execução. Em <a href="http://www.caelum.com.br/curso/pm-83-agile-scrum/">uma equipe que segue Scrum</a>, o <a href="http://en.wikipedia.org/wiki/Scrum_(development)">Scrum Master é responsável por acompanhar e detectar tais impedimentos</a>, além de ajudar a equipe a resolvê-los.</p>
<p>Equipes maduras que gerenciam seu próprio trabalho e lidam com seus próprios problemas são responsáveis por fazer tal acompanhamento, <a href="http://www.caelum.com.br/curso/pm-87-agile-praticas-ageis/">identificar e solucionar os problemas e seus impedimentos através de praticas ágeis que visam entregas de qualidade</a>.</p>
<blockquote><p>Ter esses gráficos em mãos <b>no momento necessário</b> e ser capaz de entender o que eles dizem é fundamental para um time tirar seus impedimentos da frente: seja através de seu scrum master ou de suas próprias mãos.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/seu-cliente-precisa-saber-o-andamento-do-projeto/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Prática ágil: facilite a comunicação interna</title>
		<link>http://blog.caelum.com.br/pratica-agil-facilite-a-comunicacao-interna/</link>
		<comments>http://blog.caelum.com.br/pratica-agil-facilite-a-comunicacao-interna/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 22:27:11 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Ágil]]></category>
		<category><![CDATA[agilidade]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2871</guid>
		<description><![CDATA[Sintoma: durante o processo de desenvolvimento de uma funcionalidade, a equipe se direciona ao Product Owner ou cliente para tirar dúvidas, mas o mesmo se encontra frequentemente ocupado e não pode responder. Quando o PO está livre, a equipe está concentrada em outra tarefa. Ação: crie uma lista de discussão envolvendo todos os interessados no <a href="http://blog.caelum.com.br/pratica-agil-facilite-a-comunicacao-interna/#more-2871'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/onde_trabalhar.png" width="240" />
		</p><p><strong>Sintoma</strong>: durante o processo de desenvolvimento de uma funcionalidade, a equipe se direciona ao Product Owner ou cliente para tirar dúvidas, mas o mesmo se encontra frequentemente ocupado e não pode responder. Quando o PO está livre, a equipe está concentrada em outra tarefa.</p>
<p><strong>Ação</strong>: crie uma lista de discussão envolvendo todos os interessados no projeto (Product Owner, desenvolvedores, <a href="http://blog.caelum.com.br/html-css-javascript-e-ux-na-nova-formacao-da-caelum/">User Experience</a>, clientes envolvidos com aceitação etc) e envie um email para a lista.</p>
<p>Deixamos de lado a antiga &#8220;pastelaria&#8221; que exigia disponibilidade dos desenvolvedores no exato instante do aparecimento de uma necessidade, tudo era &#8220;para agora&#8221;. O mesmo vale para o Product Owner e qualquer outro ser humano em seu trabalho.</p>
<p><a href="http://agilediary.wordpress.com/2009/10/19/product-vision-the-key-role-responsibility-of-product-owner/">Apesar de muito desejado</a>, é impossível exigir que no exato instante que surge uma dúvida da equipe de desenvolvimento, o Product Owner esteja disponível para conversar.</p>
<p>Vale lembrar que o email é uma comunicação assíncrona que leva mais tempo para obter resultados, além de ter chances de ser mal compreendido, portanto a primeira maneira a ser abordada para resolver um problema deve ser sempre a cara a cara com o PO.</p>
<p><center><div id="attachment_2874" class="wp-caption alignnone" style="width: 417px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/onde_trabalhar.png"><img class="size-full wp-image-2874" title="onde_trabalhar" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/onde_trabalhar.png" alt="Lista de discussão de um projeto/produto" width="407" height="176" /></a><p class="wp-caption-text">Lista de discussão de um projeto/produto. Criar uma lista de discussão leva 2 minutos e permite receber feedback da primeira pessoa disponível, além de facilitar a busca por conversas quando novos membros entrarem.</p></div></center></p>
<p>Como o problema é a escassez de tempo de um indíviduo específico do qual esperamos uma resposta, o envio para uma lista que envolve PO, UX e clientes diminui o tempo no escuro, sem feedback. Para evitar uma discussão, faça perguntas diretas que esperam respostas fechadas, por exemplo:</p>
<blockquote><p>
Bom dia,</p>
<p>Estamos com uma dúvida em relação a listagem de contas atrasadas.<br />
As com mais de um mês de atraso devem aparecer com outra cor,<br />
conforme o padrão da tela de faturas?</p>
<p>Nesse caso um mês é considerado 30 dias, correto? Ou precisamos ter precisão de dias de acordo com o mês?
</p></blockquote>
<p>Caso a pergunta enviada seja um pedido de aprovação de história, inicie a próxima história até receber o feedback da mesma:</p>
<blockquote><p>Bom dia,</p>
<p>As histórias A e B foram finalizadas e estão aguardando aprovação.
</p></blockquote>
<p>Caso a pergunta permanença em aberto sem resposta mesmo após o envio de um email, procure a conversa pessoal novamente: também é nosso papel como desenvolvedor conseguir a resposta, removendo impedimentos.</p>
<p>Veja também: <a href="http://blog.caelum.com.br/pratica-prefira-terminar-a-comecar-outra-historia/">prefira terminar a começar outra história</a>.</p>
<p><!-- Ver também: limite o trabalho em progresso, quando tempo eh escasso, aprove com o cliente --></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/pratica-agil-facilite-a-comunicacao-interna/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Prática: Prefira terminar a começar outra história</title>
		<link>http://blog.caelum.com.br/pratica-prefira-terminar-a-comecar-outra-historia/</link>
		<comments>http://blog.caelum.com.br/pratica-prefira-terminar-a-comecar-outra-historia/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 15:36:08 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[priorização]]></category>
		<category><![CDATA[roi]]></category>
		<category><![CDATA[scrum]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2829</guid>
		<description><![CDATA[Sintoma: Próximo ao término do ciclo de desenvolvimento (um sprint ou similar) todas as histórias estão marcadas como terminadas, resultando em uma sensação de sucesso. Mas durante a revisão das histórias pelo Product Owner, o número de recusas por detalhes pequenos é muito grande, e o número de aprovações é muito pequeno. Ação: Mesmo que <a href="http://blog.caelum.com.br/pratica-prefira-terminar-a-comecar-outra-historia/#more-2829'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p style="float:right; margin:0 0 10px 15px; width:240px;">
		<img src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/DSC05782.jpg" width="240" />
		</p><p><b>Sintoma</b>: Próximo ao término do ciclo de desenvolvimento (um sprint ou similar) todas as histórias estão marcadas como terminadas, resultando em uma sensação de sucesso. Mas durante a revisão das histórias pelo Product Owner, o número de recusas por detalhes pequenos é muito grande, e o número de aprovações é muito pequeno.</p>
<p><b>Ação</b>: Mesmo que o <a href="http://www.extremeprogramming.org/map/iteration.html">ciclo de desenvolvimento seja curto</a> &#8211; por exemplo 2 semanas &#8211; esperar o último momento para pedir aprovação é adiar as recusas e impedir as correções a tempo, algo potencializado em métodos waterfall.</p>
<p>O momento de pedir o feedback do cliente é assim que a equipe de desenvolvimento colocou a mesma em homologação (veja <a href="http://blog.caelum.com.br/desenvolvimento-o-dia-que-o-meu-projeto-parou/">deploy contínuo</a> e one click homologa).</p>
<p>Para quem utiliza um quadro físico, <a href="http://borderstylo.com/posts/66-do-you-kanban">adicione nesse instante uma coluna de aprovação pelo cliente</a>, para que o <a href="http://www.infoq.com/br/news/2010/02/quando-esta-pronto">critério de pronto</a> dependa da aprovação, que será recebida durante o ciclo de desenvolvimento.</p>
<div id="attachment_2837" class="wp-caption alignnone" style="width: 235px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/DSC05782.jpg"><img class="size-medium wp-image-2837" title="coluna de aprovado" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/DSC05782-225x300.jpg" alt="Quadro físico com coluna de &quot;aguardando aprovação&quot;" width="225" height="300" /></a><p class="wp-caption-text">Quadro físico com coluna de &quot;aguardando aprovação&quot;</p></div>
<p>Quando utilizar um sistema de tickets, crie um estado equivalente &#8220;a aprovar&#8221;, que mostre a pendência de aprovação:</p>
<div id="attachment_2835" class="wp-caption alignnone" style="width: 310px"><a href="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/pivotal.png"><img class="size-medium wp-image-2835" title="Quadros digitais com estado de aprovação" src="http://caelum.wpengine.netdna-cdn.com/wp-content/uploads/2010/07/pivotal-300x194.png" alt="Quadros digitais com estado de aprovação" width="300" height="194" /></a><p class="wp-caption-text">Quadros digitais com estado de aprovação</p></div>
<p>Quando parar: Após criado esse estado ou coluna, com o passar do tempo, é natural que o processo de pedir aprovação durante o ciclo se transforme em algo cotidiano.</p>
<p>Nesse momento é possível remover tal coluna novamente pois o mesmo já passou a fazer parte do dia a dia da equipe.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/pratica-prefira-terminar-a-comecar-outra-historia/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Desenvolvimento: o dia que o meu projeto parou</title>
		<link>http://blog.caelum.com.br/desenvolvimento-o-dia-que-o-meu-projeto-parou/</link>
		<comments>http://blog.caelum.com.br/desenvolvimento-o-dia-que-o-meu-projeto-parou/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 01:38:05 +0000</pubDate>
		<dc:creator>Guilherme Silveira</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[agilidade]]></category>
		<category><![CDATA[deploy]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[integração contínua]]></category>
		<category><![CDATA[testes]]></category>

		<guid isPermaLink="false">http://blog.caelum.com.br/?p=2345</guid>
		<description><![CDATA[Existem diversos tipos de débitos e o que todos eles tem em comum é que tornam a manutenção de um sistema muito custosa e delicada. Por mais de dois anos, a Caelum tem feito um esforço sobre cortar diversos tipos de débitos técnicos, incluindo levar práticas ao extremo, como testes end-to-end em grid. Uma forma <a href="http://blog.caelum.com.br/desenvolvimento-o-dia-que-o-meu-projeto-parou/#more-2345'" class="more-link">more &#187;</a>]]></description>
			<content:encoded><![CDATA[<p>Existem diversos tipos de débitos e o que todos eles tem em comum é que tornam a manutenção de um sistema muito custosa e delicada.</p>
<p>Por mais de dois anos, a Caelum tem feito um <a href="http://blog.caelum.com.br/o-processo-de-deploy-continuo/">esforço sobre cortar diversos tipos de débitos técnicos</a>, incluindo levar práticas ao extremo, como <a href="http://blog.caelum.com.br/integracao-continua-builds-rapidos-com-grids-e-paralelismo/">testes end-to-end em grid</a>.</p>
<p>Uma forma de enxergar que devemos melhorar o processo de desenvolvimento é verificar que perdemos dinheiro ao tomar decisões <a href="http://agilenomundoreal.wordpress.com/2010/03/30/um-produto-por-semana/">ou muito cedo</a>, <a href="http://agilenomundoreal.wordpress.com/2010/03/04/como-criar-e-priorizar-um-backlog/">ou tarde demais</a>.</p>
<p>O <strong>descuido</strong> gera débitos que cortam a produtividade de sua equipe. Também o <strong>excesso de cuidado</strong>, <a href="http://www.wired.com/magazine/2009/12/fail_duke_nukem/">gera muitas trocas de decisões, visando o preciosismo técnico</a>, pode levar a um atraso muito grande.</p>
<p>Além disso, uma empresa que espera 4 meses para colocar algo em produção pode ser uma empresa 4 meses atrás de seus concorrentes. Entregar valor tardio é ficar para trás.</p>
<p>Mas o que causa empresas ágeis a não entregar tão frequentemente? </p>
<p>Muito produtos criados em ambientes ágeis só são colocados em produção  depois de muito tempo. Durante todo esse tempo, os únicos a testarem e aprovarem as funcionalidades são a equipe de QA e o Product Owner. Ao colocar este produto em produção depois de um ciclo tão grande, o cliente final vai encontrar <a href="http://en.wikipedia.org/wiki/IBM_Rational_Unified_Process">os problemas que costumavam aparecer em metodologias tradicionais</a>. </p>
<p>No lado gerencial, o Product Owner apresenta dificuldades em priorizar seu backlog de maneira a entregar valor, acabando por entregar funcionalidades. Além disso, é dificil aceitarmos algo &#8220;incompleto para o uso mínimo&#8221; e, na visão de quem é dono de um produto, o &#8220;mínimo necessário&#8221; acaba sendo maior do que o real e nunca é atingido para ser colocado em produção. É aí que seu projeto para: ele ficara sem entregas durante muito tempo.</p>
<p>Existe uma prática bem simples para um PO executar e perceber se possui essas dificuldades. Olhe seu penúltimo sprint e veja as funcionalidades que já estão sendo utilizadas por seu cliente. Agora jogue na fórmula:</p>
<blockquote><p>GPD = (salario da equipe * pontos_desnecessários) / pontos_do_sprint</p></blockquote>
<p>GPD é o <strong>G</strong>asto que você teve com <strong>P</strong>riorização <strong>D</strong>esnecessária durante o penúltimo sprint. Ser ágil é entregar valor, e <a href="http://www.dtsato.com/blog/2009/07/04/velocity-gone-wrong-2-making-up-points/">seus pontos estão sendo utilizados em funcionalidades completas sem tanto valor</a>. Se existiam outras tarefas que entregavam valor para os usuários, a priorização poderia ter sido melhor.</p>
<p>Outra possível melhora na parte gerencial está na execução de testes somente por QAs e POs: o feedback não vem do cliente final. Devemos entregar cedo e frequentemente para receber feedback real, e não apenas do PO. Mas como alcançar isso se o produto possui um conjunto mínimo de funcionalidades, que é razoavelmente grande, para entrar em produção?</p>
<p>Assim como diversos ramos de software, adote o conceito de usuários beta. Ele possuem acesso a suas funcionalidades mais cedo, em servidores suficientemente estáveis que acessam dados de produção, rodando a última versão de seu produto, mas com o risco de algo dar errado. O conceito de beta potencializa a propaganda do seu produto,  <a href="http://www.uberreview.com/2008/01/25-signs-that-you-might-be-an-apple-fanboy.htm">podendo criar uma legião</a> de fanboys.</p>
<p>Na parte técnica, desenvolvedores tem percebido cada vez mais a importância de todos tipos de testes automatizados, controle de versão, integração contínua e outras práticas com base em XP, mas outra causa ainda mais comum de problemas em diversas empresas é <a href="http://www.agileadvice.com/archives/2005/05/truck_factor.html">o truck factor</a>. Se durante a reunião de planejamento alguém responde que determinada tarefa é dele &#8211; pois ele  &#8220;conhece mais aquela parte do sistema&#8221; &#8211; ou se alguém é o único que vota os pontos de parte do sistema; ou ainda se é comum esperarem por alguém para executar qualquer tarefa,  está na hora de compartilhar mais o conhecimento e acabar com esse impeditivo antes que o <em>truck</em> acabe com ele. Parear e ensinar mais o que conhecemos permite que, ao invés de produzirmos por nós mesmos, diversas pessoas produzam através do que compartilhamos. Essa é a mágica do ensino, levado ao pareamento. Não parear por causa daquela parte ser responsabilidade de uma única pessoa é um paradoxo! É justo esse tipo de caso que mais ganha vantagens do pareamento.</p>
<p>O outro fator para desenvolvedores e sysadmins se perguntarem é quanto tempo leva para fazer deploy? Alguns dias? Se sim, a metodologia ágil que foi alcançada perdeu grande parte do seu valor pois o feedback rápido virou feedback semanal ou ainda mensal.</p>
<p>Apesar de processos de build automatizados junto com integração contínua serem importantes, <a href="http://blog.caelum.com.br/integracao-continua-deploys-e-aprovacoes-sem-dores-de-cabeca-para-o-cliente/">deploy contínuo é cada vez mais fundamental</a>.</p>
<p>Essas e outras práticas, gerenciais ou técnicas, servem para encontrar o que está implicando na não-entrega de valor ao cliente. Depois de detectado esse gargalo, devemos  agir para melhorar nosso processo de desenvolvimento.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.caelum.com.br/desenvolvimento-o-dia-que-o-meu-projeto-parou/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

