Por que criar um objeto Logger em vez de usar métodos de log estáticos em um aplicativo?

14

Tomando um exemplo de uma simples aplicação Ruby on Rails. Ele cria um Loggerobjeto durante o processo de carregamento do aplicativo:

# in environment.rb
config.logger = Logger.new(<STDOUT | file | whatever>)

# and in our application we use this object
logger.warn "This process is taking too long to process. Optimization needed."

Minha pergunta é: por que não usamos métodos de classe (ou métodos estáticos) para o log? Não vai Logger.warnescalar Logger.new.warn? Ou pelo menos Logger.warnparece intuitivo que Logger.new.warn.

Mesmo que Logger.newseja um objeto singleton, que vantagens ele oferece?

Harsh Gupta
fonte

Respostas:

17

Aqui está um exemplo que usa Java. Já faz um tempo desde que usei o log4j, mas pelo que me lembro, toda a ferramenta de log do log4j seria inicializada a partir de um arquivo XML. O próprio arquivo XML pode conter vários criadores de logs com configurações diferentes (onde você escreve, em que níveis são gravados etc.). Portanto, nesse caso, você teria objetos de criador de logs em vez de métodos estáticos de criador de logs para especificar qual criador de logs deseja chamar. Ou seja.

Logger logger = Logger.get("Network");

registraria coisas relacionadas à conectividade de rede, pacotes descartados etc. ou

Logger logger = Logger.get("Application");

que registraria itens relacionados à sua aplicação / lógica comercial. Pelo menos com o log4j, você também pode configurar quais níveis de log são realmente gravados (informações, rastreamento, aviso, erro, depuração sendo os níveis padrão disponíveis).

Se você tivesse métodos estáticos, o melhor que você poderia fazer é configurar um único criador de logs que apontaria para um padrão, um arquivo etc., mas tudo o que você registraria iria para o mesmo local. Com os objetos do criador de logs, é mais fácil fazê-lo para que suas informações de registro sejam espalhadas em vários arquivos.

Shaz
fonte
Obrigado. Isso também ajudou a entender quando usar métodos estáticos.
Harsh Gupta
2
Embora eu prefira instanciar um objeto para fazer meu log, como demonstrado aqui, é bastante comum (eu diria preferível) acessá-lo estaticamente, em vez de passá-lo a todas as chamadas de métodos. O registro é apenas um tipo de natureza global.
Chad Schouggins
Também é importante notar que há momentos em que podemos querer configurar o criador de logs estendendo-o (ou fornecendo uma implementação de alguma interface e fornecendo isso ao criador de logs). Isso seria utilizado para fazer algo como alterar o destino do log (além do que os arquivos de configuração podem permitir). Você provavelmente tornaria a instância específica estática, como mencionado no @ChadSchouggins.
Kat
2

Logger.new é uma fábrica que levará onde o resultado será usado (nome da classe / arquivo).

Nos arquivos de configuração, você pode decidir em que nível registrar, para não registrar em partes do programa sem precisar recompilar o projeto.

Assim, você pode desativar todos os logs (de alto nível), exceto os de alto nível, para compilações de release e ativar apenas o nível mais baixo para as partes que você está depurando.

catraca arrepiante
fonte
2

A invocação de método estático deve ser evitada sempre que possível. É uma alternativa antiquada à injeção de dependência adequada, e não é algo que você achará útil em uma base de código maior.

Considere testabilidade, por exemplo. A chamada estaticamente de registro coloca o Assunto em teste no controle de qual classe de registro é usada - não há Inversão de controle. Não há possibilidade de injetar um objeto falso ou qualquer tipo de falsificação aqui. Ao injetar o logger no SUT, você descobrirá que tem a opção de zombar do logger e injetá-lo.

Os benefícios do uso de DI sobre o tipo de chamada de método estático em discussão vão além da testabilidade, é claro. Considere o que aconteceria se você desejasse ter dois registradores diferentes em seu sistema e a opção de alterar o comportamento do aplicativo apenas através da configuração do gráfico de objetos, sem editar o código existente.

No geral, eu sugiro que você tente uma abordagem de DI, para que você não encontre seu código imprestável e pesado posteriormente.

Sam Burns
fonte