Eu tenho um projeto que é suficientemente grande e não consigo mais manter todos os aspectos da minha cabeça. Estou lidando com várias classes e funções e passando dados.
Com o tempo, notei que continuava recebendo erros, porque esqueci a forma precisa dos dados quando os transmito para diferentes funções ( por exemplo, uma função aceita e gera uma matriz de strings, outra função, que escrevi muito mais tarde, aceita seqüências de caracteres que são mantidas em um dicionário etc., portanto, eu tenho que transformar as seqüências de caracteres com as quais estou trabalhando, de tê-las em uma matriz para tê-las em um dicionário ).
Para evitar sempre ter que descobrir o que ocorreu onde, comecei a tratar cada função e classe como uma "entidade isolada", no sentido de que não pode confiar no código externo, fornecendo a entrada correta e tem que executar as verificações de entrada (ou, em alguns casos, reformule os dados, se os dados forem fornecidos na forma errada).
Isso reduziu bastante o tempo que gasto, certificando-me de que os dados que eu transmito "se encaixam" em todas as funções, porque as próprias classes e funções agora me alertam quando alguma entrada é ruim (e às vezes até corrige isso) e eu não tem que ir com um depurador por todo o código para descobrir onde algo deu errado.
Por outro lado, isso também aumentou o código geral.
Minha pergunta é, se esse estilo de código apropriado para resolver esse problema?
Obviamente, a melhor solução seria refatorar completamente o projeto e garantir que os dados tenham uma estrutura uniforme para todas as funções - mas, como esse projeto cresce constantemente, eu acabaria gastando mais e me preocupando com o código limpo do que realmente adicionando coisas novas. .
(FYI: ainda sou iniciante, desculpe se essa pergunta foi ingênua; meu projeto é em Python.)
fonte
Respostas:
Uma solução melhor é tirar mais proveito dos recursos e ferramentas da linguagem Python.
Esse problema é mitigado com um
namedtuple
. É leve e oferece um significado semântico fácil para os membros da sua matriz.Para aproveitar os benefícios de alguma verificação automática de tipo sem alternar idiomas, você pode tirar proveito das dicas de tipo . Um bom IDE pode usar isso para informar quando você faz algo estúpido.
Você também parece preocupado com as funções ficando obsoletas quando os requisitos mudam. Isso pode ser detectado por testes automatizados .
Embora eu não esteja dizendo que a verificação manual nunca é apropriada, um melhor uso dos recursos de idioma disponíveis pode ajudá-lo a resolver esse problema de uma maneira mais sustentável.
fonte
namedtuple
e para todas as outras coisas legais. Eu nãonamedtuple
sabia - e, embora eu soubesse sobre o teste automatizado, nunca o usei muito e não percebi o quanto isso me ajudaria neste caso. Tudo isso realmente parece ser tão bom quanto uma análise estática. (O teste automatizado pode até ser melhor, pois consigo captar todas as coisas sutis que não seriam capturadas em uma análise estática!) Se você conhece algum outro, informe-me. Vou manter a pergunta em aberto por mais um tempo, mas se não houver outras respostas, eu aceito as suas.OK, o problema real é descrito em um comentário abaixo desta resposta:
O problema aqui é o uso de uma lista de strings em que o pedido significa semântica. Esta é realmente uma abordagem propensa a erros. Em vez disso, você deve criar uma classe personalizada com dois campos chamados
title
ebibliographical_reference
. Dessa forma, você não irá confundi-los e evitar esse problema no futuro. É claro que isso requer alguma refatoração se você já usa listas de cadeias de caracteres em muitos lugares, mas acredite, será mais barato a longo prazo.A abordagem comum em linguagens de tipos dinâmicos é a "digitação de pato", o que significa que você realmente não se importa com o "tipo" do objeto passado, mas apenas se ele suporta os métodos que você chama. No seu caso, você simplesmente lerá o campo chamado
bibliographical_reference
quando precisar. Se esse campo não existir no objeto passado, você receberá um erro e isso indica que o tipo errado é passado para a função. É uma verificação de tipo tão boa quanto qualquer outra.fonte
Primeiro, o que você está enfrentando agora é o cheiro do código - tente lembrar o que o levou a ficar consciente do cheiro e tente aprimorar o nariz "mental", pois quanto mais cedo você notar um código, mais cedo - e mais fácil - você é capaz de corrigir o problema subjacente.
A programação defensiva - como essa técnica é chamada - é uma ferramenta válida e frequentemente usada. No entanto, como em todas as coisas, é importante usar a quantidade certa, poucas verificações e você não detectará problemas, muitas e seu código ficará sobrecarregado.
Essa pode ser uma ideia menos boa. Se você perceber que uma parte do seu programa está chamando uma função com dados formatados incorretamente, CORRECIONE A PARTE , não altere a função chamada para poder digerir os dados incorretos de qualquer maneira.
Melhorar a qualidade e a manutenção do seu código economiza tempo a longo prazo (nesse sentido, devo advertir novamente sobre a funcionalidade de autocorreção que você incorporou em algumas de suas funções - elas podem ser uma fonte insidiosa de bugs. programa não falha e queima não significa que funciona corretamente ...)
Para finalmente responder à sua pergunta: Sim, a programação defensiva (ou seja, verificar a validade dos parâmetros fornecidos) é - em um nível saudável - uma boa estratégia. Dito isto , como você mesmo disse, seu código é inconsitente, e eu recomendo fortemente que você gaste algum tempo para refatorar as partes que cheiram - você disse que não deseja se preocupar com código limpo o tempo todo, gastando mais tempo com "limpeza" do que em novos recursos ... Se você não mantiver seu código limpo, poderá gastar duas vezes o tempo "salvar" de não manter um código limpo em erros de esmagamento E terá dificuldade em implementar novos recursos - a dívida técnica pode esmagar você.
fonte
Tudo bem. Eu costumava codificar no FoxPro, onde eu tinha um bloco TRY..CATCH quase em todas as grandes funções. Agora, eu codigo em JavaScript / LiveScript e raramente verifico parâmetros em funções "internas" ou "privadas".
"Quanto verificar" depende mais do projeto / idioma escolhido do que da sua habilidade com o código.
fonte