Como as pessoas costumam ser muito rápidas em apontar, um dos benefícios do software é que é fácil e relativamente barato mudar em comparação com o hardware. Isso é especialmente importante quando você percebe tarde que algo está errado. Faça o mesmo com o hardware e você perderá um milhão de dólares; portanto, como já disse, usa seus simuladores, etc., e testa o bazinga com ele. Acho que é aí que o paradigma falha um pouco quando você muda para o software.
Entre na cabeça do desenvolvedor de software comum, e o que você tem é uma pessoa muito ocupada, com um prazo incrivelmente apertado. Seu gerente está dizendo que não há problema em deixar alguns erros, porque você sempre pode corrigi-lo mais tarde. Os testes geralmente são uma reflexão tardia, mas mesmo em um cenário orientado a testes, os testes são mantidos mínimos e o código é gravado no mínimo dos testes, e geralmente são atalhos para que muitos dos casos de fronteira possam ser perdidos. O sistema pode ser exaustivamente testado em unidade, mas raramente é rigorosamente testado como um todo, e tão raramente quanto testado em grande escala. Acrescente a isso que você escreve software do zero e há poucas oportunidades de simular o software antes de se comprometer a escrevê-lo, principalmente porque raramente escrevemos software com o mesmo tipo de blocos de construção refinados que você encontraria no hardware.
De volta à pergunta do OP. Você poderia definir um sistema de blocos de construção para derivar todo o seu software? Possivelmente. Seria muito rentável? Provavelmente não, porque no momento em que você começa a desenvolver um sistema robusto o suficiente de componentes, testes e outras parafernálias para suportar esse idealsistema de programação, você descobriria que sua concorrência já o derrotaria no mercado e, pior ainda, do ponto de vista do programador médio, você provavelmente acharia um estilo de sistema de programação "cortador de biscoitos" muito limitador e provavelmente muito entediante. Pessoalmente, trabalho em uma API, onde a maior parte do código do módulo foi refinada e padronizada tão completamente, que tudo o que faço agora é gerar um modelo de código e preencher os espaços em branco. A maior parte do meu tempo pode ser gasta escrevendo código de conector simples e colocando os módulos fora da porta o mais rápido possível. É seriamente entorpecente. Há muito pouca oportunidade de fazer mais do que apenas codificar os mesmos tipos de coisas repetidas vezes; portanto, quando outra oportunidade de projeto aparece, aproveito a chance de poder fazer QUALQUER OUTRA COISA.
Então, como você pode entregar software de alta qualidade e bem fatorado e ainda assim se divertir fazendo isso? Acredito que isso se resume a sua escolha de ferramentas e metodologia. Para mim, a resposta foi empregar o uso de uma boa API BDD, porque me permitiu criar um código muito fácil de ler, mas altamente granular. Posso criar um conjunto de testes com um número mínimo de métodos reutilizáveis e descrever meus testes no idioma das especificações. Dessa maneira, chego perto de uma abordagem de desenvolvimento mais componente, exceto pelo fato de ser responsável por projetar e verificar os blocos de construção. Além disso, a saída do teste identifica a parte exata do teste em que a falha ocorre, para que eu não precise adivinhar se as falhas estão na configuração ou na afirmação.
Ajustar sua metodologia também ajuda. Sou um grande defensor da aplicação de princípios de desenvolvimento enxuto e de combiná-los com muitas das outras técnicas e princípios com os quais o movimento Agile está discutindo há muitos anos. Tendo eliminado a maioria das práticas inúteis que costumava achar tão frustrantes, ajudou muito a tornar o desenvolvimento uma atividade mais agradável. Ainda me resta a questão de que, às vezes - mas espero que não com muita frequência - bugs apareçam no meu código, agora eu me encontro com mais tempo e ainda mais incentivo para gastar mais tempo escrevendo testes mais robustos e buscando 100 % de cobertura de teste. Melhor ainda, é ótimo ver todas essas luzes verdes aparecerem no final do meu dia,