Za pomocą AOP mogę usunąć kod logowania z logiki biznesowej. Ale myślę, że można go używać tylko do rejestrowania prostych rzeczy (tj. Rejestrowania metody wejścia / wyjścia i wartości parametrów).
A jeśli jednak muszę coś zalogować w logice biznesowej? na przykład
public void SomeDomainMethod(string id)
{
//Get user by Id
User user = Users.Get(id);
if (user == null)
{
Log.Warn("user is not existed"); //<----------------- Log A
throw new InvalidOperationException("user is not existed");
}
//Step 1
while(true)
{
//do something
}
Log.Info("Step 1 is completed"); //<----------------- Log B
//Step 2
while(true)
{
//do something
}
Log.Info("Step 2 is completed"); //<----------------- Log C
}
Powyższa przykładowa metoda może nie być wystarczająco jasna, co chcę tutaj pokazać, że metodę należy traktować jako najmniejszą jednostkę z punktu widzenia domeny. Nie należy go dzielić na mniejsze części.
Czy można wyjść z metody powyżej 3 kodów logowania? Jakie są najlepsze praktyki w takiej sytuacji?
c#
logging
separation-of-concerns
Charlie
źródło
źródło
Odpowiedzi:
Pewnie!
Ale z mojego doświadczenia wynika, że istnieją dwa ogólne typy przydatnych rejestrowania:
Wszystko loguje: Logi budowane poprzez API profilujące. Dobry do identyfikowania problemów z wydajnością i zgłaszania wyjątków. Bardzo głośny.
Dzienniki zdarzeń biznesowych : dzienniki wywoływane w logice biznesowej. Wszystko, o co może dbać firma. Minimalny hałas. Po prostu godne uwagi, logiczne zdarzenia „biznesowe”. Dobry do kontroli i kluczowych wskaźników wydajności ...
Chciałbym więc bardzo zasugerować dwie rzeczy. Po pierwsze, rób to, co robią inne narzędzia monitorowania, takie jak New Relic, i korzystaj z interfejsu API profilowania .NET 1 . Po drugie, loguj logiczne zdarzenia biznesowe w logice biznesowej . Prowadzenie rejestru niektórych zdarzeń jest logiką biznesową.
I normalnie nie sugerowałbym AOP dla żadnego rodzaju logowania 2 . Z mojego doświadczenia wynika, że albo chcesz wszystkiego , co oznacza, że używasz profilera, albo chcesz zdarzeń logicznych / biznesowych. W drugim przypadku myślę, że łatwiej jest po prostu wywołać program rejestrujący w logice biznesowej.
1. Ale poważnie, zaoszczędź tysiące godzin wysiłku i po prostu użyj istniejącego narzędzia do profilowania ...
2. Oczywiście zakłada to, że podzielasz moją opinię, że aspekt nie jest doskonałym miejscem do ukrywania reguł biznesowych!
źródło
Jasne, możesz do tego łatwo użyć AOP. Po prostu refaktoryzuj części
na osobne metody (tak jak powinieneś to zrobić, aby uczynić kod czystszym). Teraz możesz łatwo skonfigurować środowisko AOP, aby rejestrowało wybrane wywołania metod ( jak pokazano tutaj ). Wyjątek może zostać zarejestrowany bezpośrednio przez osobę dzwoniącą, nie trzeba używać AOP, aby uzyskać to z logiki biznesowej.
Do twojej edycji:
Dlaczego by nie miał? Jeśli w „kontekście logiki biznesowej” chcesz zarejestrować „coś”, co jest warte zarejestrowania, i jeśli to „coś” można nadać sensownej nazwie, w większości przypadków sensowne jest przeformułowanie kodu na metodę własny. Jeśli chcesz korzystać z AOP, będzie to wymagało ustrukturyzowania kodu w taki sposób, że prawdopodobnie powinieneś go ustrukturyzować niezależnie od wymogu rejestrowania. Możesz zinterpretować to jako wadę AOP lub zinterpretować to jako korzyść, ponieważ daje ona informację zwrotną, w której można poprawić strukturę kodu.
źródło
O ile rejestrowanie danych nie jest częścią wymagań biznesowych, najlepiej, jak mówisz, całkowicie ukryć swój kod.
Oznacza to, że naprawdę nie chcesz rejestrować takich rzeczy, jak „ukończono krok 1”. Chociaż początkowo może być przydatny do debugowania, podczas produkcji po prostu wygeneruje gigabajty śmieci, których nigdy nie obejrzysz.
Jeśli Step1Complete jest jakimś wydarzeniem biznesowym, które wymaga dalszych działań, może zostać ujawnione poprzez dobre, stare wydarzenie bez zmuszania Cię do wstrzyknięcia ILoggera lub podobnego do twojej klasy
źródło
Za pomocą jakiegoś wspólnego wzorca możesz wyciągnąć kod logowania z logiki biznesowej. Jednak może nie być tego warte
Na przykład, używając listenera (rzemieślniczego lub używając magistrali zdarzeń itp.), Twój kod będzie wyglądał
Po zaimplementowaniu rejestrowania w detektorze logika logowania nie jest już używana w logice biznesowej.
Jednak może się okazać, że nie zawsze jest to realistyczne, ponieważ nie zawsze możesz zdefiniować znaczące zdarzenie swojej logiki.
Innym podejściem jest mechanizm taki jak Dtrace w Solarisie, który pozwala ci wstrzykiwać się do uruchomionych procesów (uważam, że można zrobić podobne rzeczy w C #?), Dzięki czemu można zdefiniować rejestrowanie i statystyki w czasie wykonywania. Nadal istnieją inne wady.
źródło
Innym podejściem jest oddzielenie rejestrowania danych biznesowych i rejestrowania technicznego. Następnie możemy nazwać rejestrowanie danych biznesowych „Audytem” i zastosować określony zestaw reguł biznesowych, takich jak warunki przechowywania i reguły przetwarzania, takie jak Monitorowanie aktywności biznesowej.
Z drugiej strony rejestrowanie techniczne lub po prostu „rejestrowanie” jest środkiem ostatecznym do pozostawienia śladu problemów technicznych. Powinien być asynchroniczny, szybki, odporny na nietrwałość komunikatu dziennika. Ponadto komunikaty dziennika powinny przechodzić przez możliwie najmniejszą liczbę serwerów proxy, aby znajdować się blisko źródła problemu.
Logika rejestrowania jest dość zmienna i ściśle związana z implementacją, więc czy naprawdę musisz oddzielić ją od kodu?
Logika audytu powinna być traktowana jako logika domeny i odpowiednio traktowana.
Na przykład w architekturze heksagonalnej może istnieć port audytu wraz z portami klientów, pamięci masowej i MQ (i ewentualnie metryk i kontroli). Byłby to port pomocniczy, tzn. Aktywność na tym porcie jest uruchamiana przez rdzeń biznesowy, a nie przez systemy zewnętrzne.
źródło
Sposoby unikania bezpośredniego logowania do klasy lub metody:
Rzuć wyjątek i zaloguj się w bloku catch dalej w górę drzewa połączeń. Jeśli chcesz przechwycić poziom dziennika, możesz zgłosić niestandardowy wyjątek.
Wywoływaj metody, które są już oprzyrządowane do logowania.
źródło
Czy naprawdę konieczne jest oddzielenie rejestrowania od logiki biznesowej? Rejestrowanie odbywa się zgodnie z zapisaną logiką biznesową i dlatego ma sens bycie w tej samej klasie / funkcji. Co ważniejsze, pomaga łatwiej odczytać kod.
Jednak jeśli naprawdę chcesz oddzielić rejestrowanie od logiki biznesowej, powinieneś rozważyć wprowadzenie niestandardowych wyjątków i przekazanie tych wyjątków do rejestrowania.
źródło
Nie, nie w c #
OP, odpowiedź na twoje konkretne pytanie brzmi: nie, nie w c #. Mogą istnieć inne, bardziej rodzime języki AOP, ale wszystkie podejścia do AOP w języku c #, które widziałem, mogą stosować tylko zachowania podejrzane w kontekście punktu łączenia , co oznacza, że musi istnieć przepływ kontroli między jednym blokiem kodu a inne. Aspektowane zachowania nie będą wykonywane w trakcie metody, z wyjątkiem oczywiście wywołania innej metody.
Możesz „apsect-ize” pewne fragmenty logowania
To powiedziawszy, możesz wyciągnąć pewne obawy związane z logowaniem, po prostu nie zapisywać dziennika. Na przykład punkt odcięcia, który jest wykonywany przy wejściu do metody, może skonfigurować kontekst rejestrowania i wyprowadzić wszystkie parametry wejściowe, a przy wyjściu może wychwycić wyjątki lub przekazać dziennik do pamięci trwałej, tego rodzaju rzeczy.
W każdym razie zapisywanie dziennika nie jest aspektem
Dodałbym, że pisanie dziennika nie jest w rzeczywistości przekrojowym problemem. Przynajmniej nie rejestruj debugowania. Dowodem na to jest to, że nie można napisać przekrojowego wymogu, który w pełni wyjaśnia, co zrobiłby ten aspekt - jest specyficzny dla każdego przypadku, ponieważ celem zapisu dziennika jest odzwierciedlenie tego, co się dzieje z logika, a logika w każdej metodzie powinna być w miarę unikalna (patrz OSUSZANIE ).
Innymi słowy, istnieje nierozerwalna logiczna zależność między pisaniem dziennika a tym, co jest pisane. Nie możesz tego uogólnić.
Ale audyt jest
Jeśli masz jakieś funkcjonalne wymaganie dotyczące rejestrowania (np. Rejestrowanie kontroli w celu obsługi wymogu niezaprzeczalności ), to niektórzy twierdzą (i zgodzę się), że jeśli będziesz musiał wykonać te zapisy dziennika w środku metody, nie ustrukturyzowałeś swojego kodu w sposób zgodny z myśleniem aspektowym. Jeśli tak się stanie, należy wyodrębnić kod do osobnych metod, aż do uzyskania wymaganego poziomu szczegółowości.
źródło