Acabei de ler o link do artigo que você postou, devo dizer que Fowler fez alguns pontos muito bons e muitas coisas que ele disse, venho advogando com nossa equipe há anos.
Na IMO, se você faz um design decente, não deve entrar no que seria considerado uma situação sem saída. Eu sempre vi o software como composto de blocos de construção . Ainda acredito em algum projeto inicial, mas o objetivo principal não é projetar o produto inteiro, mas fornecer uma arquitetura / direção geral para que sua equipe possa visualizar uma imagem comum na qual estamos trabalhando. Se você tem um monte de peças de cubo e triângulo, é útil esboçar como um castelo seria montado antes de você simplesmente começar a bater as peças.
Como eu venho da terra OO, para mim cada bloco é uma classe e a área de superfície desse bloco é a interface pública (o que é visível por classes externas ou derivadas). Se você seguir bons princípios do SOLID, garantirá que cada bloco seja extremamente simples e tenha uma interface pública intuitiva. Voltando à minha analogia, você quer ter certeza de que o código cria apenas formas simples. Sempre que você cria classes complexas demais (muitas funções, muitas variáveis), cria formas difíceis de reutilizar quando os requisitos mudam.
Concordo com Fowler em que o maior risco / desafio para o design evolutivo é que você deixa as decisões de design com tempo de codificação e espera que cada desenvolvedor individual tome essas decisões. É aqui que o sistema pode quebrar se você não tiver mecanismos de feedback adequados em vigor. Sempre que um novo recurso é solicitado, é extremamente tentador simplesmente encontrar a função que precisa ser estendida, colocar algum tipo de condicional dentro dele e apenas adicionar um monte de código dentro dessa função. E, às vezes, isso pode ser tudo o que é necessário, mas essa também é (IMO) a prática mais comum que leva a componentes sem saída. Isso não tem nada a ver com design evolucionário. Isso é chamado de "sem design".
Contanto que você reserve um tempo para recuar e dizer, espere um minuto, esta classe já possui 15 variáveis de membro, deixe-me extrair 6 delas e colocá-las em sua própria classe independente, seu software será composto de muita luz blocos de construção leves, flexíveis e reutilizáveis. Certamente, se os PMs aparecerem e mudarem metade dos requisitos de produtos, talvez seja necessário retirar alguns blocos, colocá-los novamente na prateleira e elaborar outros novos (como na construção de um castelo, você não pode usar todos seus cilindros). Mas, nesse ponto, isso faz parte dos negócios. Os requisitos foram alterados e, mantendo seu código flexível e modular, você poderá alterar seu produto para se alinhar com a nova direção de negócios.
Acredito que essa abordagem evolutiva do design funcione com todos os níveis de habilidade do engenheiro. Pessoalmente, faço software há muito tempo e, antes de nossa equipe mudar para a metodologia ágil, eu era responsável pelo envio de vários componentes principais do meu PC de desenvolvimento quase diretamente ao cliente, com quase nenhum controle de qualidade. Ao mesmo tempo, esses componentes sempre permaneceram flexíveis e sustentáveis.
Só estou tentando dizer que me consideraria relativamente decente ao projetar software. Ao mesmo tempo, se você me pedisse para escrever um documento de design de 100 páginas, entregá-lo a um codificador e esperar que funcionasse, provavelmente não conseguiria me projetar com um saco de papel. Ao iniciar o trabalho, algumas vezes eu esboçava alguns diagramas do tipo UML (muito simplificado, não em linguagem completa), mas, ao começar a codificar, refatava conforme necessário e meu código final nunca se pareceria com o que eu originalmente desenhei. Mesmo se eu passar um mês ou dois pensando em cada pequeno detalhe, não consigo imaginar alguém capaz de pegar meus diagramas e criar um software sólido sem modificar o design à medida que eles estão codificando.
No outro extremo do espectro, atualmente em minha equipe (agora ágil e eu apóio isso), temos alguns caras que se juntaram a nós de terras incorporadas, onde fizeram C apenas nos últimos 15 anos. Obviamente, eu ajudei no planejamento inicial e na criação de aulas, mas também me assegurei de acompanhar revisões regulares de código e sessões de brainstorming, nas quais discutimos aplicações do SOLID e dos princípios de design. Eles produziram algum código de espaguete que me fez estremecer um pouco, mas com apenas um leve empurrão de mim, eles começaram a refatorar o que já havia sido produzido e a parte engraçada é que um deles voltou para mim alguns dias depois e disse: Eu odeio Para dizer isso, mas depois de mudar esse código, isso parece muito mais legível e compreensível. Beco sem saída evitado. Ponto I ' O que estou tentando fazer é que mesmo alguém que seja completamente novo no OO possa produzir um código decente, desde que ele tenha um mentor com mais experiência, para lembrá-lo de que "design evolucionário" não é a mesma coisa que "sem design". E mesmo algumas de suas classes "mais complexas" não são tão assustadoras, porque cada classe não tem tanta responsabilidade (ou seja, não há tanto código), então o pior fica pior, se essa classe "acabar", nós jogue-o fora e escreva uma classe de substituição que tenha a mesma interface pública (até agora nunca vi necessidade dessa contingência em nada que escrevemos e tenho feito revisões de código duas vezes por semana).
Como observação final, eu também acredito firmemente nos documentos de design (pelo menos para as condições de negócios da minha equipe atual), mas o objetivo principal dos nossos documentos de design é a Memória Organizacional ; portanto, documentos reais são gravados após a produção do código e refatorado. Antes da codificação, geralmente temos uma fase de design rápida (às vezes não tão rápida), onde esboçamos aulas sobre guardanapos / mspaint / visio e eu sempre lembro às pessoas que essa fase produz um caminho a seguir, não um blueprint e quando eles começam a codificar, qualquer coisa que não faça sentido deve ser mudada. Mesmo com esses lembretes, os novatos tendem a tentar adaptar o código ao design original, por mais natural que pareça para eles. Isso geralmente aparece nas revisões de código.
Dang, eu escrevi muito. Me desculpe por isso.