So I don't waste much time on writing super clean code at that point because I never know how long something lasts.
Não saber quanto tempo dura alguma coisa nunca deve ser uma desculpa para desleixo - muito pelo contrário. O código mais limpo é IMHO o que não entra em seu caminho quando você tem que mudar alguma coisa. Portanto, minha recomendação é: sempre tente escrever o código mais limpo possível - especialmente quando estiver codificando um protótipo. Porque será muito mais fácil adaptá-lo quando algo tiver que ser mudado (o que certamente irá acontecer).
Não me entenda mal - minha compreensão do "código mais limpo" não tem nada a ver com tornar o código bonito por causa da beleza. Isso é realmente algo que pode atrasar você. No meu ponto de vista, código limpo é o código que é mais auto-explicativo (não é necessário gravar tantos documentos - acelera), fácil de entender (menos erros, menos depuração necessária - aumento de velocidade, menos tempo necessário para encontrar o correto lugar para alterar - acelerar), resolve o problema dado com a menor quantidade de código necessário (menos código para depurar - speedup óbvio), é DRY (apenas um lugar para mudar quando algo tem que ser mudado - aceleração - e menor risco de introduzir novos bugs esquecendo de mudar um segundo lugar), segue padrões de codificação (coisas menos complicadas para se pensar - speedup), usa blocos de construção pequenos e reutilizáveis (que podem ser reutilizados para muitos recursos ou até mesmo protótipos) e assim por diante.
I am expected to start testing/final debugging but my gut says I should now somehow clean up and or rewrite stuff to give it proper architecture that makes maintenance etc easier
Fazer "limpeza" depois nunca funciona. Considere que você limpa antes de implementar um novo recurso, ou quando começar a implementá-lo, mas não depois. Por exemplo, sempre que você começar a tocar em um método para um recurso e perceber que ele ultrapassa 10 linhas, considere refatorá-lo em métodos menores - imediatamente , antes de concluir o recurso. Sempre que você detectar uma variável ou um nome de função existente, você não sabe exatamente o que isso significa, descubra para que serve e renomeie a coisa antes de fazer qualquer outra coisa. Se você fizer isso regularmente, mantenha seu código pelo menos em um estado "limpo o suficiente". E você começa a economizar tempo - porque você precisa de muito menos tempo para depurar.
I am in the middle of testing and the bug fix would be a rewrite
... que é a prova real para o que eu escrevi acima: ser assombrações "sujas" imediatamente de volta quando você começar a depurar seu código e irá torná-lo mais lento.
Você pode evitar isso quase completamente se fizer a limpeza imediatamente. Em seguida, correções de bugs significam principalmente pequenas alterações no código, mas nunca uma alteração arquitetural importante. Se você realmente detectar evidências de melhorias na arquitetura durante o teste, adie-as, coloque-as no sistema de rastreamento de problemas e implemente-as na próxima vez que você precisar implementar um recurso que se beneficie dessa alteração ( antes você começar com esse recurso).
Isso requer alguma disciplina e alguma experiência em codificação, é claro. É uma ideia semelhante à idéia por trás do "desenvolvimento orientado a testes", fazendo essas coisas de antemão em vez de executá-las posteriormente (o TDD também pode ajudar, mas o que escrevi funciona mesmo quando você não usa o TDD). Quando você fizer isso consequentemente, você não precisará de nenhuma "fase de limpeza" especial antes de liberar.