Categories
Engenharia de software

Cuidando para que o software não apodreça

Infeliz o sujeito que teve a idéia de comparar desenvolvimento de software a construção de prédios. Até hoje, em pleno século 21, algumas pessoas ainda acreditam que para fazer software você deve fazer exatamente como na construção civil: você deve ter “engenheiros” que fazem um grande projeto especificando exatamente como tudo vai ser, depois os pedreiros constroem e no final está tudo pronto e funcionando conforme a especificação.

Desenvolvimento de software não tem absolutamente nada a ver com construção!

No livro The Pragmatic Programmer, Dave Thomas e Andy Hunt fazem uma analogia muito mais apropriada: fazer software não é como constriur prédios mas sim como jardinagem. É muito mais “orgânico” do que “concreto”. Inicialmente você planeja muitas coisas para o seu jardim de acordo com as condições atuais de terra, clima, etc. Você precisa plantar as sementes, regar todo dia e cuidar para que as pragas não acabem com tudo. Você pode com o passar do tempo mover suas plantas de lugar para tirar vantagem de fatores como exposição ao sol, sombra ou até mesmo para fazer a rotatividade da terra. Você poda suas plantas constantemente e move alguns tipos de flores de um lugar para o outro para que o jardim fique melhor esteticamente. Se alguma planta cresce demais, pode ser que o espaço que você planejou para ela tenha ficado pequeno, e então é necessário movê-la de lugar. Enfim, não é uma coisa que você planeja, mas sim uma coisa que você tem uma idéia inicial e trabalha ao longo do tempo para fazer o melhor possível dentro daquela idéia.

Assim como o jardim, se o software não receber todos os cuidados necessários ele apodrece. Quando um software apodrece, é impossível implementar qualquer funcionalidade num tempo aceitável, é impossível colocar em produção sem que alguém tenha que ficar de babá, enfim, tudo passa a ser imprevisível. Nos piores casos passa a ser até impossível “tocar” no software, e esses monstros viram aqueles softwares que “se o servidor desligar ele não liga nunca mais”. E o pior é que isso acontece toda hora. Quantas vezes você já não pegou um projeto tão ruim, mas tão ruim que seria mais fácil fazer do zero do que consertá-lo? Isso é um sinal claro de software podre.

Para evitar que isso aconteça, o que se deve fazer é reavaliar a situação do software a cada história/funcionalidade implementada. Um bom desenvolvedor sempre avaliará se não é hora de mover algumas coisas de lugar, generalizar algumas funcionalidades, reescrever algumas porções de código e etc. – assim como faria um bom jardineiro. Isso deveria ser uma lei, não uma opção.

Os times ágeis trabalham com um conceito que é a “definição de pronto” (DOD – definition of done). A definição de pronto diz quando é que uma funcionalidade pode ser considerada pronta ou finalizada. Na minha opinião, para se considerar uma funcionalidade “pronta” é necessário no mínimo:

  • Desenvolver a funcionalidade
  • Testar unitariamente (melhor ainda se for fazendo TDD)
  • Testar a integração com outros componentes (quando for o caso)
  • Verificar se o build do projeto funciona sem erros e fazer o deploy em uma ambiente de produção simulado
  • Testar segundo os critérios de aceitação estabelecidos pelo cliente
  • Depois dos testes desenvolvidos e a nova funcionalidade passando em todos eles, avaliar a necessidade de fazer refactoring no novo código
  • Com a entrada da nova funcionalidade, avaliar a necessidade de fazer refactoring em algum módulo do sistema
  • Atualizar a documentação (quando necessário)

Pode parecer um exagero ou muito trabalho, mas não é. A questão é que você não pode deixar para fazer nenhum desses itens depois de 2 meses de desenvolvimento, você precisa fazer isso desde o primeiro dia! Quando você deixa para depois, você acaba acumulando o famoso débito técnico, e depois poderá ter que pagá-lo com juros, que poderão ser muito altos. O melhor é fazer aos poucos, a cada passo dado, porque desta forma o trabalho sempre será muito menor e não irá onerar o projeto. Mais uma vez fazendo analogias, é como câncer: você pode se previnir e tentar evitar que ele aconteça, ou você pode esperar ficar doente para depois ter que fazer uma arriscada cirurgia invasiva (e mesmo assim pode não dar certo, e aí perde-se o paciente).

30 replies on “Cuidando para que o software não apodreça”

Legal o post, Guilherme! Lendo as referências ainda..

Falamos bastante sobre isso no último review, e decidimos incluir também que:
* todos do time devem ter revisado aquela história (código e interface)

Como o PO não vê nenhum sinal de apodrecimento no início (talvez sinta o cheiro mais tarde..), você acha que o ScrumMaster deve ser ativo na cobrança por qualidade? (assim como o PO cobra valor de negócio entregue) Ou é o time que tem que se tocar mesmo? :p

abraço.

Fala Pedro!

Legal a história da revisão. No nosso time temos uma regra que o cara que implementou é diferente do cara que testa, que é diferente do cara que faz o teste final de aceitação. Sendo assim, a coisa passa na mão de pelo menos 3 pessoas e a revisão acaba acontecendo naturalmente.

Quanto a cobrança por qualidade, acho que isso deve ser uma obrigação de todos. Eu particularmente sempre “brigo” por isso com o meu time e tento passar algum conhecimento/experiência que eu tenho sobre o assunto – da mesma forma que eu faria em qualquer papel que estivesse desempenhando. Nem chega nem a ser difícil pois a maioria já está mais do que “test-infected” 🙂

Enfim, eu acho que se o Scrum Master tem conhecimento e argumentos para cobrar qualidade, não vejo motivo para que não o faça. Se ele não é tão técnico que não consiga entender a importância, é essencial que o time seja maduro suficiente para tratar dessas questões.

[ ]s, gc

Nunca gostei dessa analogia com jardinagem. A meu ver, o papel do Scrum Master parece com o do Jardineiro, que fica cortando, podando, plantando mudas e jogando sementes nos locais certos para que as plantas cresçam no rumo planejado. No entanto, o resto da equipe tem uma responsabilidade maior em fazer do que em “cortar as pontas”. Como ninguém faz uma planta crescer, simplesmente espera, a analogia fica um tanto quebrada.

Não sei se você já acompanhou a construção de uma casa de classe média (não de um prédio). A analogia para a planta de uma casa não deve ser entendida como aquele monte de documentos imutáveis do rup e do desenvolvimento em cascata que as especificações nunca são alteradas, mas sim como as tuas user stories. A planta da casa representa o desejo do cliente (Imagine seus testes de aceitação). Esta planta vai mudar, porque o cliente vai ver como a casa ficou na realidade e, provavelmente, não vai gostar de algumas coisas.

Eu gosto da analogia de construção de casas porque você constrói a casa em partes, assim como o software. Primeiro o fundamento, depois as paredes, a hidráulica e elétrica, o piso e o teto. Após a pintura, colocação de piso, gesso, móveis, etc. As vezes acontecem coisas como: os operários se reunírem para começar e concluir o banheiro no mesmo dia. Isso é como nós fizemos software. Primeiro a arquitetura (fundamento), depois testa-se a principal user story para ver se funciona (paredes), depois as outras junto com a lógica de negócios que transita entre as US (redes hidráulica e elétrica), acompanhado das regalias de user interface.

Guilherme, olhando os passos para se considerar uma funcionalidade “pronta”:

* Desenvolver a funcionalidade
* Testar unitariamente (melhor ainda se for fazendo TDD)
* Testar a integração com outros componentes (quando for o caso)
* Verificar se o build do projeto funciona sem erros e fazer o deploy em uma ambiente de produção simulado
* Testar segundo os critérios de aceitação estabelecidos pelo cliente
* Depois dos testes desenvolvidos e a nova funcionalidade passando em todos eles, avaliar a necessidade de fazer refactoring no novo código
* Com a entrada da nova funcionalidade, avaliar a necessidade de fazer refactoring em algum módulo do sistema
* Atualizar a documentação (quando necessário)

Não é melhor fazer o refactoring antes dos testes? Por que se você fizer um refactoring, provalmente vai ter que refazer os testes para “garatir” a qualidade.

@Vitor

Desculpa me meter aqui… Mas é exatamente essa analogia (construção de casas) que não queremos para o desenvolvimento de software.

Cada funcionalidade construída do software deve ser algo que possa ser usado pelo usuário final, que traga valor para ele. Não queremos fazer toda a camada de acesso ao BD para depois fazer a camada de serviços e por último a interface do usuário.

Usando a sua analogia, a forma que defendemos de construir software, seria construir, por exemplo, o banheiro inteiro, com absolutamente tudo para ele funcionar: fundamentos, instalação hidráulica, elétrica, acabamentos, decoração. Só aí partiríamos para a construção da sala e assim por diante. Obviamente sabemos que uma casa não é construída assim, por isso a analogia não valeria.

Abs.,

Guilherme Cirne

Oi Rubem,

Essa minha linha de raciocínio é baseada no princípio que “vc deve fazer a coisa mais simples que possa funcionar”. Isso normalmente fará com que vc faça código que seja necessario para os testes passarem, e não mais do que isso. Depois, com o código coberto por testes e já funcionando, você pode refatorar correndo um risco menor de quebrá-lo.

Eu prefiro esse tipo de abordagem, fazendo tudo em “baby steps”.

De qualquer forma, se vc tiver que fazer refactoring nos testes por algum motivo, não vejo porque não. A base de código de testes merece tanta atenção/refactoring quanto o resto 🙂

[ ]s, gc

@Vitor, o @Guilherme Cirne tem razão.

Você não pode entregar uma casa toda só com paredes e sem encanamento, certo? Desse jeito só daria para usá-la no fim da construção. Da mesma forma em software, você não pode entregar somente a “arquitetura do software” sem nada funcionando porque isso não tem valor para o cliente. Em desenvolvimento iterativo e incremental (como é feito em “metodologias” de desenvolvimento ágil), entrega-se uma coisa do início ao fim. Cada história tem sua arquitetura, desenvolvimento, testes, deployment e etc.

Isso que vc propôs é desenvolvimento waterfall.

[ ]s, gc

Concordo plenamente com o @Guilherme Chapiewski e com o @Guilherme Cirne.

Bom, por quê?

Primeiro porque atualmente assumi um projeto que está podre e não podre por estar dificil em sua manutenção(aliás está também dificil) e sim porque o cliente não usa absolutamente nada do que está pronto.

Penso eu que se o software tivesse sido construído aos poucos, como realmente deve ser feito, hoje não teríamos um cliente com um baita “Godzilla” nas mãos sem saber o que fazer com ele.

E o pior, nossa equipe teme em colocar as mãos nesse bicho, pois com certeza não sabemos o que pode acontecer mais pra frente.

E o pior de tudo é que com algumas semanas conseguimos perceber que o usuario apenas queria algo simples, isso que me deixa louco da vida.

Você desenha uma mansão, começa a construir uma mansão aos poucos, o seu cliente nao entende nada do que você está fazendo e acredita que você esteja construindo realmente o que ele precisa e por fim você entrega uma casa, com 2 a 3 andares e esqueceu de reparar que seu cliente usa “muletas” e não pode ficar subindo e descendo escadas, e o pior, o piso térreo tem apenas 2 salas e garagens, que nao serve nem pra dormir, nem pra ir ao banheiro e muito menos pra se alimentar.

Lamentável.

Mas é a situação atual em que estou.

Mas nosso time aos poucos está conseguindo introduzir a ideia de se con struir algo beeeeeemmmm menor mas que seja útil para nosso cliente.

@Guilherme Chapiewski, me desculpe pela analogia e pelo texto extenso, mas essa história de se comparar construção de casa com desenvolvimento de software é totalmente insano.

Excelente post, aliás, esse post já foi compartilhado em nosso time.

Abraços.

Fabio Nascimento.

Não concordo. O fato de eu desenvolver o banheiro (ou qualquer outra parte/feature) inteiro primeiro (se assim optar) é para deixá-lo funcionando para o cliente a pedido dele (prioridades) e já permitir o seu uso (small releases).

Você pode usar a sua casa sem o telhado (Segurança), só não pode chover (Mesma coisa que fazer um ERP sem se preocupar com Autorização de usuários) 🙂

Da mesma forma que eu software, o cliente não vai usá-lo sem o básico dos requisitos implementados (fundamentação, paredes e telhado). Depois disso, ele pode vir morar na casa a hora que quiser, só que vai se incomodar com o pessoal ainda trabalhando nela (assim como acontece com software).

Que merda… estou começando a detestar analogias. Dá muita margem a interpretações.

@GC

Realmente, se procura desenvolver um software da forma correta, seguindo o principio do KISS, boas práticas, etc, o refactoring tende a ser menos problemático.

É que eu acho que pelo menos esse passo:
“* Testar segundo os critérios de aceitação estabelecidos pelo cliente”

Tem que ser feito (também) no final, antes da ultima mexida, por menor que ela seja, para “garantir” que o projeto funciona.

Apenas adicionando ao Post do @GC. Ken Schwaber chama este software podre de “dead core”, e se vcs lerem o capitulo 9 pag.93 do livro “The Enterprise and SCRUM” onde ele descreve o que é um dead core irão se identificar imediatamente :-), pelo menos quem já passou por isso.

Além disso como vc pode adaptar a analogia da construção civil ao desenvolvimento de software no caso do refactoring? Quando Quarto, Sala, Cozinha, banheiro estiverem prontos, como vc faz para trocar a fundação? Ai é que esta, não faz! Mais um exemplo de porque é uma péssima analogia.

Falando em analogias a Mary Poppendieck faz uma analogia muito boa entre desenvolvimento e produção, usando um exemplo de um restaurante:

“Desenvolvimento é bem diferente de produção, Pense que o desenvolvimento é como criar uma receita e que a produção é como seguir (executar) esta receita. Estas são atividades muito diferentes, e elas deveriam ser resolvidas com abordagens diferentes. Desenvolver uma receita é um processo de aprendizado envolvendo tentativas e erros. Você não espera que a primeira tentativa de um Chef, de nível internacional, ao fazer um novo prato seja sua última tentativa. Na verdade, toda a idéia de desenvolver uma receita tem o objetivo de testar muitas variações e descobrir o melhor prato.
Uma vez que o Chef tenha descoberto a receita, para preparar o prato, basta seguir a receita.”

Muito bom o post GC !
Acho que este artigo da margem a uma continuação muito boa, por exemplo:
“O que fazer quando o software apodreceu ?”

Já que este é o meu caso e de muitos pelo jeito … 🙂

[]s

Quantos de nós já não passaram por isto?

“Software is not physical. It’s certainly not sexy. All I have to do is answer the question, ‘What do you do?’ at any party to learn how absolutely uninteresting my chosen profession is. I say, ‘I work with software,’ and the questioner visibly glazes over and turns to the next person. (Or worse, they grill me about using Photoshop. I’ve never used Photoshop in my life.) I’ve come to dread that question.”

@Fabio

É só você olhar as grandes instituições que não se importam quanto se gasta para desenvolver software, jogar rios de dinheiro – que não lhes faltam – no ralo e, de qualquer modo, os atende. Eles não querem saber, não estão preocupado com o que é certo ou errado, pois o fator crucial é o risco – para eles – de mudar ou não. Eu mesmo ouvi isso e no meu último emprego, um martírio de dois meses:

“Não Fagner, ninguém quer saber, ninguém quer mudar nada. Eles querem é vender seguros e se ainda estão vendendo bem então que continue assim”

Infeliz o dia em que saí da Globo.com rsrs

As analogias citadas até aqui cobrem alguns aspectos do desenvolvimento, mas não possuem a mesma abrangência da analogia da “Construção de prédio”. Não estou dizendo que ela seja boa, mas ela se mostra muito atraente tanto por ser mais próxima de “negócios” como por cobrir muitas dimensões. Vamos assumir que queremos ilustrar as seguintes dimensões:

1) a natureza criativa e colaborativa do trabalho;
2) o caráter iterativo/incremental da construção das soluções visadas;
3) a temporalidade e a complexidade crescente dessas soluções;

Vou tentar aqui uma analogia que me agrada mais, usando um pouco da inspiração do que já ouvi falarem na comunidade Ruby. Desenvolvimento de Software parece um pouco com composição de música. Mas se o software em questão for um sistema maior e de longa duração, pode ser que a melhor analogia seja com as composições de uma Banda de música! Um disco, um show, uma carreira. Envolve arte, técnica e negócios. No caso do trabalho/obra, seria algo como um trabalho encomendado, onde essa “encomenda” lembra a forma como antigamente as óperas eram financiadas, alguém com dinheiro suficiente querendo uma peça musical que atenda suas necessidades (Um requiem? Uma homenagem? Entretenimento baseado em alguma *história* ou *tema*?). Os integrantes colaboram nas composições e por precisarem atender a um “mecena/patrocinador” faz sentindo exibirem a composição aos poucos (iterativamente) para ver se agrada/atende aos “requisitos” (muitas vezes nebulosos) e de uma forma simplificada, afinal não faz sentido orquestrar um rascunho! Enfim, é possível equiparar uma banda a uma equipe de desenvolvimento e seus trabalhos. Eis alguns pontos que me ocorrem:

– Ter que atender a um Produtor/Patrocinador (Gerentes, Analistas de negócio) e ainda por cima ao público (Usuário final) para fazer sucesso não é tarefa fácil, ou esses intermediários fazem um papel muito bom como proxy do mercado ou é melhor se aproximar mais do público para saber o que realmente desejam ou então ser alguém parecido com seu próprio público, o caso é: estar bem próximo das fontes de necessidades e/ou anseios.
– Durante os primeiros rascunhos executados nem todos os trechos/músicas precisam estar no mesmo grau de maturidade, na versão final (se o escopo/tempo permitir) as coisas podem mudar bastante até a gravação final, ou mesmo depois, se considerarmos os shows ao vivo (freqüentemente há variações).
– A unidade “música” pode ter semelhanças com uma classe ou um pacote de classes (dependendo da complexidade), ou mesmo um “tema” (no sentido usado na teoria musical) se assemelha a uma classe, uma vez que pode ser usada várias vezes numa mesma música e até em outras de uma mesma obra (disco? ópera?).
– Novas encomendas com “requisitos” semelhantes podem reutilizar partes das soluções anteriores (ou técnicas). Muitas vezes isso extrapola a própria banda. Talvez por isso vejamos tantas bandas e/ou músicas parecidas num determinado período de tempo.
– Várias coisas podem ser “acopladas” ao trabalho musical, tais como: clipes, capas de cd, coreografias, livros, etc. Outras vezes são pensadas juntas desde o começo, como ocorre às vezes em trilha de filmes, musicais ou óperas. Artistas/técnicos de outras áreas agregam valor tal qual designers aos sistemas baseados na web, daí ser importante saber trabalhar com pessoas de outras áreas.
– Treino e disciplina são importantes para dominar ferramentas, compor melhor e executar melhor em conjunto e sem erros. Não adianta crescer sozinho ou só saber tocar solos, é uma banda!
– O relacionamento da banda tem que ser cultivado e mantido sadio para a banda sobreviver e continuar criativa.
– O valor não está nos instrumentos, mas em quem os usa. De pouco serve a melhor guitarra do mundo na mão de alguém que não sabe usá-la em todo seu potencial. Ou, quão bom músico pode ser considerado quem só sabe usar aquelas Pick ups de Dj para mixar música dos outros (“apertador de parafusos de frameworks”)?
– A banda vai fazendo seus “discos” e vai precisando se renovar, se não fizer muitos sucessos novos o número de músicas “legado” (antigos sucessos) vai aumentando e deixando os shows mais complexos e chatos para os mesmos. A idéia é não ser uma banda de um sucesso só ou presa a um passado que não consegue superar. Se a Banda não se preocupar em se atualizar e melhorar corre o risco de só tocar em “Festas da Saudade”…
– Quanto mais os integrantes da Banda treinarem e comporem coisas fora de sua zona de conforto melhor músicos se tornarão.

Enfim, como toda analogia tem falhas. Mas não precisa ser mesmo perfeita, basta ser suficiente para ajudar na comunicação de algumas idéias.

Pois é @seufagner, tanta gente querendo entrar na globo.com (Eu !!!) e você saiu ?

O que se passou em sua cabeça ?

Mas realmente, você tem razão, nossa realidade, ou minha realidade atual desanima.

Mas um dia em consigo um trabalho em que realmente o que importa é a satisfação do cliente ou “produto entregue (Scrum)”.

Abraços.

Fabio Nascimento

Me pergunto duas coisas:

1 – Por que nunca comparamos desenvolvimento de software com desenvolvimento de software mesmo? Sempre temos que inventar nossas analogias… (eu mesmo tenho um bocado)

2 – Com o que será que o pessoal da engenharia comparava as construções no começo dessa ciência? 🙂

Excelente post!
Willi

Independente de toda discussão em relação a metáfora. Achei super interessante ler seu texto e retornar à “Definição de Pronto”.

Puxa… A dedicação diária para não neglicenciar as práticas e valores que estamos aprendendo fazem TODA a diferença.

Não vamos deixar nossos softwares apodrecerem e nos fazerem pensar que seria melhor ser “Florista” à ser Desenvolvedor.

Leave a Reply to 1up4Developers » Blog Archive » Arquiteto Cascateiro Cancel reply

Your email address will not be published. Required fields are marked *