O cenário a seguir me aconteceu várias vezes.
Programei um algoritmo que resolve um determinado problema. Funciona bem e encontra as soluções corretas. Agora, quero ter uma opção para informar ao algoritmo "escreva uma explicação completa de como você chegou à solução". Meu objetivo é poder usar o algoritmo em demonstrações online, aulas tutoriais, etc. Ainda quero ter a opção de executar o algoritmo em tempo real, sem as explicações. O que é um bom padrão de design para usar?
EXEMPLO: Suponha que eu implemente esse método para encontrar o maior divisor comum . O método implementado atual retorna a resposta correta, mas sem explicações. Quero ter uma opção para o método explicar suas ações, como:
Initially, a=6 and b=4. The number of 2-factors, d, is initialized to 0.
a and b are both even, so we divide them by 2 and increment d by 1.
Now, a=3 and b=2.
a is odd but b is even, so we divide b by 2.
Now, a=3 and b=1.
a and b are both odd, so we replace a by (a-b)/2 = 1.
Now, a=1 and b=1.
a=b, so the GCD is a*2^d = 2.
A saída deve ser retornada para que possa ser facilmente exibida no console e em aplicativos baseados na Web.
Qual é um bom padrão para fornecer explicações quando necessário, sem prejudicar o desempenho em tempo real do algoritmo quando as explicações não são necessárias?
fonte
Um bom padrão é o Observer. https://en.wikipedia.org/wiki/Observer_pattern
No seu algoritmo, em cada ponto em que você deseja gerar algo, você notifica alguns observadores. Eles então decidem o que fazer, seja para enviar seu texto no console ou enviá-lo para o mecanismo HTML / Apache etc.
Dependendo da sua linguagem de programação, pode haver diferentes maneiras de torná-lo rápido. Por exemplo, em Java (trate-o como pseudocódigo, por questões de brevidade; torná-lo "correto", com getters, setters, é deixado para o leitor):
Isso é um pouco detalhado, mas a verificação de
==null
deve ser o mais rápida possível.(Observe que, no caso geral,
observer
provavelmente seria umaVector observers
alternativa para permitir mais de um observador; isso também é possível e obviamente não levará a mais sobrecarga; você ainda pode colocar a otimização que definiu emobservers=null
vez de ter um esvaziarVector
.)Obviamente, você implementaria diferentes tipos de observadores, dependendo do que você deseja alcançar. Você também pode inserir estatísticas de tempo etc., ou fazer outras coisas sofisticadas.
fonte
Como uma ligeira melhora no registro direto, crie algum tipo de objeto que modele uma execução do algoritmo. Adicione uma "etapa" a esse objeto de contêiner toda vez que seu código fizer algo interessante. No final do algoritmo, registre as etapas acumuladas no contêiner.
Isso tem algumas vantagens:
EDIT: Como comentado por outros, as lambdas têm sobrecarga, portanto, você teria que fazer um benchmark para garantir que essa sobrecarga seja menor que a avaliação desnecessária do código necessário para construir a cadeia de log (as entradas de log geralmente não são literais simples, mas envolvem a obtenção de informações contextuais. objetos participantes).
fonte
Geralmente procuro a ramificação, o que significa que procuro instruções if. Porque estes indicam que eu avalio um valor, que controlará o fluxo do algoritmo. Em cada ocorrência (cada condição), posso registrar o caminho escolhido e por que ele foi escolhido.
Então, basicamente, eu registraria os valores de entrada (estado inicial), todos os ramos escolhidos (condicionais) e os valores ao inserir o ramo escolhido (estado temporário).
fonte