INTRODUÇÃO
Como desenvolvedor, sempre fui fascinado por design de software. Comumente definida como a atividade de especificar os componentes de software (classes) e suas interações, considero a tarefa desafiadora e bastante interessante. Quando comecei a entrar em contato com princípios de desenvolvimento ágil (em especial SCRUM e XP), percebi que havia uma grande incompatibilidade entre o que aprendi na faculdade (e acreditava ser a forma correta de fazer design) e o que pregam as metodologias.
UP FRONT DESIGN
Aprendi na faculdade que design é fase da engenharia de software que faz a ponte entre a especificação de requisitos e a construção propriamente dita. O analista decide O QUE fazer, o projetista decide COMO fazer e o programador FAZ. O produto da fase de design são documentos e diagramas que o desenvolvedor irá usar para construir o software que o analista idealizou. Esta abordagem hoje é chamada de up front design e sem dúvida não é livre de seus problemas e desafios:
- É muito difícil (senão impossível) criar antecipadamente um design tal que atenda todos os requisitos (funcionais e não-funcionais) e esteja livre de falhas.
- Seria necessário criar um design que fosse flexível suficiente para acomodar as temíveis mudanças de requisitos. Mesmo que seja possível, qual seria o custo em complexidade de um design assim?
No SCRUM não há fase de design. Há uma reunião onde o product owner explica para o time em detalhes as características de cada item do sprint backlog e a partir daí analistas começam a documentar, testers especificam casos de testes e programadores começam a desenvolver. Simples assim. Não tem design? Não da forma como aprendi na faculdade.
EVOLUTIONARY DESIGN
Se não é possível gerar um design que atenda a todos os requisitos, seja livre de falhas e se não é possível evitar mudanças de requisitos, o que justifica o esforço (geralmente grande devido a natureza complexa da atividade) despendido na criação de um up front design? Entendendo que codificar é projetar as metodologias ágeis propõem algo chamado evolutionary design.Nesta abordagem, o design e codificação andam lado a lado. O design evolui de acordo com as necessidades das funcionalidades sendo construídas. Não há o papel formal de projetista nem um momento específico para desenvolver o design: Todos os desenvolvedores fazem e refazem o design todos os dias.
YAGNI
Um dos conceitos mais intrigantes relacionados a evolutionary design é conhecido pela sigla YAGNI (You Aren't Gonna Need It). “Sempre escreva apenas o código que você precisa agora, nunca o que você vai precisar amanhã” Mesmo que você tenha absoluta certeza de que vai precisar daquele trecho de código e que o custo de escreve-lo seja zero: Deixe para fazê-lo quando for necessário.YAGNI é contra-intuitivo porque vai contra aquilo que acredita-se ser maior benefício de um um bom design: antecipação de complexidade e consequente redução de riscos. Entretanto, existem bons argumentos em favor desta abordagem:
- Respeito ao ROI do cliente: Escrever código que não agrega valor a funcionalidade em construção é desrespeitar a priorização do product owner e consecutivamente o ROI do cliente.
- Economia de tempo: O tempo usado para escrever código que só será usado posteriormente pode fazer falta na hora de entregar as funcionalidades previstas para esta iteração.
- Possíveis mudanças: Escrever código antecipadamente é um risco (desnecessário) porque o entendimento pode ter sido equivocado ou a lógica/regra pode mudar, gerando a necessidade de reescrever o código.
FAZENDO EVOLUTIONARY DESIGN FUNCIONAR
Neste ponto, o leitor já deve ter percebido que um projeto que usar evolutionary design corre grandes riscos de acabar mesmo é sem design, ou com um design muito pobre.Críticos acusam evolutionary design de ser super-dependente da maturidade do time, o que tem um fundo de verdade. Neste sentido, o XP define o papel do Coach, que seria um desenvolvedor mais experiente com a responsabilidade de orientar o time nas decisões técnicas (inclusive de design).
Além disso, existe uma série de práticas, do próprio mundo ágil ou não, que acredito devam ser empregadas criteriosamente de forma a manter a qualidade do design:
- Ênfase em testes (unitários, de integração, etc..): É importante ter uma boa margem de segurança quando são feitas mudanças de design.
- Integração contínua: Integrar o código do projeto como um todo (mantendo o time em sincronia) buscando detectar o mais cedo possível possíveis problemas de design.
- Pair program: Se a funcionalidade for muito complexa, colocar 2 desenvolvedores responsáveis por ela pode ser uma boa ideia.
- Análise caixa branca: Incluir uma tarefa de inspeção de código a fim de detectar design inadequado (devido ao auto custo, a análise poderia ser feita por amostragem apenas)
- Lista de boa práticas: Manter uma lista de boas práticas que sirva de orientação aos desenvolvedores. Tal lista seria incrementada ao longo do projeto com a experiência adquirida.
CONCLUSÕES
O mundo ágil não tem lugar para up front design em sua forma conceitual, como uma fase bem definida e buscando “prever” todas as nuances do desenvolvimento de uma funcionalidade, mas poderia se beneficiar de algumas de suas caraterísticas como redução de riscos e forte padronização.Evolutionary design é a abordagem alternativa que os métodos ágeis indicam, porém ele deve ser empregada em conjunto com outras práticas que garantam a qualidade do design do software a ser construído.
REFERÊNCIAS
Excelente artigo de Martin Fowler sobre design e XP (http://martinfowler.com/articles/designDead.html)Artigo sobre problemas de up front design (http://architects.dzone.com/news/great-lies-design-vs)
Nenhum comentário:
Postar um comentário