Po co tworzyć obiekt Logger zamiast statycznych metod rejestrowania w aplikacji?

14

Biorąc przykład prostej aplikacji Ruby on Rails. Tworzy Loggerobiekt podczas procesu ładowania aplikacji:

# 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."

Moje pytanie brzmi: dlaczego nie używamy metod klasy (lub metod statycznych) do logowania? Czy nie będzie Logger.warnskali niż Logger.new.warn? Lub przynajmniej Logger.warnwydaje się intuicyjny niż Logger.new.warn.

Nawet jeśli Logger.newjest to obiekt singletonowy, jakie oferuje zalety?

Ostra Gupta
źródło

Odpowiedzi:

17

Oto przykład wykorzystujący Javę. Minęło trochę czasu, odkąd użyłem log4j, ale z tego co pamiętam, całe narzędzie do logowania log4j zainicjowałoby się z pliku XML. Sam plik XML może zawierać wiele programów rejestrujących o różnych konfiguracjach (gdzie piszesz, jakie poziomy są zapisywane itp.). Tak więc w tym przypadku mielibyśmy obiekty rejestrujące, a nie metody statyczne rejestratora, aby określić, który rejestrator ma zostać wywołany. To znaczy.

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

rejestruje rzeczy związane z łącznością sieciową, upuszczanymi pakietami itp. lub

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

który rejestruje rzeczy związane z logiką / aplikacją biznesową. Przynajmniej przy pomocy log4j możesz również skonfigurować, które poziomy logów faktycznie są zapisywane (informacje, śledzenie, ostrzeganie, błąd, debugowanie są domyślnymi dostępnymi poziomami).

Jeśli masz metody statyczne, najlepiej jest skonfigurować pojedynczego programu rejestrującego, który wskazywałby na standardowe wyjście, plik itp., Ale wszystko, co logujesz, trafiłoby w to samo miejsce. W przypadku obiektów rejestrujących łatwiej jest to zrobić, aby dane logowania były rozłożone na wiele plików.

Shaz
źródło
Dzięki. Pomogło to również w zrozumieniu, kiedy stosować metody statyczne.
Harsh Gupta
2
Chociaż wolę tworzyć instancję obiektu w celu rejestrowania, jak pokazano tutaj, dość powszechne (powiedziałbym, że preferowane) jest uzyskiwanie do niego dostępu statycznego zamiast przekazywania go do każdego wywołania metody. Rejestrowanie ma charakter globalny.
Chad Schouggins,
Warto również zauważyć, że są chwile, w których możemy chcieć skonfigurować rejestrator poprzez rozszerzenie go (lub zapewnienie implementacji jakiegoś interfejsu i przekazanie go do rejestratora). Można to wykorzystać do zmiany miejsca docelowego rejestrowania (poza tym, na co pozwalają pliki konfiguracyjne). Prawdopodobnie spowodowałbyś, że konkretna instancja była statyczna, jak wspomniano @ChadSchouggins.
Kat
2

Logger.new to fabryka, która zabierze miejsce, w którym zostanie wykorzystany wynik (nazwa klasy / pliku).

W plikach konfiguracyjnych możesz następnie zdecydować, na jakim poziomie logować się, aby nie logować się wcale dla części programu bez konieczności ponownej kompilacji projektu.

W ten sposób można wyłączyć rejestrowanie wszystkich błędów oprócz błędów dla wersji kompilacji i aktywować najniższy poziom tylko dla debugowanych części.

maniak zapadkowy
źródło
2

Tam, gdzie to możliwe, należy unikać wywoływania metod statycznych. Jest to przestarzała alternatywa dla prawidłowego wstrzykiwania zależności, a nie jest to coś, co można znaleźć w większej bazie kodu.

Rozważ na przykład testowalność. Statyczne wywoływanie rejestrowania poddaje podmiot badany kontroli, która klasa rejestrowania jest używana - nie ma odwrócenia kontroli. Nie ma tu możliwości wstrzyknięcia fałszywego przedmiotu ani żadnej podróbki. Wstrzykując rejestrator do SUT, przekonasz się, że masz możliwość wykpienia rejestratora i wstrzyknięcia go.

Oczywiście korzyści z zastosowania DI w porównaniu z rodzajem wywoływanej metody statycznej wykraczają poza testowalność. Zastanów się, co by się stało, gdybyś chciał mieć dwa różne programy rejestrujące w swoim systemie, a także opcję zmiany zachowania aplikacji poprzez samą konfigurację wykresu obiektowego, bez edytowania istniejącego kodu.

Podsumowując, sugeruję wypróbowanie podejścia DI, więc nie znajdziesz później kodu, który byłby niestabilny i niewygodny.

Sam Burns
źródło