Jaki jest dobry przykład cross-cutting concern? Przykładowa dokumentacja medyczna na stronie wikipedii wydaje mi się niekompletna.
W szczególności z tego przykładu, dlaczego rejestrowanie miałoby prowadzić do powielania kodu ( rozpraszania )? (Oprócz prostych połączeń, takich jak log("....")wszędzie, co nie wydaje się być wielką sprawą).
Jaka jest różnica między a core concerni a cross-cutting concern?
Zanim zrozumiemy problem przekrojów , musimy zrozumieć ten problem .
Koncern jest termin, który odnosi się do części systemu podzielonej na podstawie funkcji.
Obawy są dwojakiego rodzaju:
Obawy reprezentujące pojedynczą i określoną funkcjonalność dla wymagań podstawowych są znane jako problemy podstawowe .
LUB
Podstawowa funkcjonalność systemu jest najważniejsza. Na przykład : logika biznesowa
Obawy dotyczące funkcji dla wymagań drugorzędnych nazywane są kwestiami przekrojowymi lub problemami ogólnosystemowymi .
LUB
Problem przekrojowy jest problemem, który ma zastosowanie w całym wniosku i dotyczy całego wniosku. Na przykład: logowanie, bezpieczeństwo i transfer danych to kwestie, które są potrzebne w prawie każdym module aplikacji, stąd są to zagadnienia przekrojowe.
Ta liczba przedstawia typową aplikację, która jest podzielona na moduły. Głównym celem każdego modułu jest świadczenie usług dla określonej domeny. Jednak każdy z tych modułów wymaga również podobnych funkcji pomocniczych, takich jak logowanie bezpieczeństwa i zarządzanie transakcjami. Przykładem problemów związanych z przecinaniem jest „rejestrowanie”, które jest często używane w aplikacjach rozproszonych w celu ułatwienia debugowania przez śledzenie wywołań metod. Załóżmy, że robimy rejestrowanie zarówno na początku, jak i na końcu ciała funkcji. Spowoduje to przecięcie wszystkich klas, które mają co najmniej jedną funkcję.
„Problem przekrojowy dotyczy całego wniosku” ➤ Nie jestem tego pewien, ponieważ zarządzanie transakcjami nie ma zastosowania „w całym” wniosku, ale nadal jest problemem przekrojowym. A zdjęcie nic mi nie mówi, żeby być uczciwym, jest tylko mylące ...
Koray Tugay
Dobre wyjaśnienie, ale mam mały problem z obrazem, w którym nazywamy te obawy, zagadnieniami przekrojowymi, a nie przekrojowymi, i byłoby lepiej, gdybym pomyślał, że wyeliminowałbym inne problemy związane z kwestiami przekrojowymi, a nie inną drogą. Podobnie jak rozwój zorientowany na
aspekt
nadal odpowiedź nie wyjaśnia problemu, używając po prostu czegoś takiego jak Log4j i logowania, takiego jak LogManager.getLogger (). info (ModuleName, msg)
Vicky Singh
49
Myślę, że najlepszym przykładem przekrojowego problemu jest zachowanie transakcyjne. Na przykład konieczność umieszczania bloków try-catch z wywołaniami commit i rollback we wszystkich metodach usług byłaby odstraszająca. Oznaczanie metod znacznikiem, którego AOP może użyć do hermetyzacji ich pożądanym zachowaniem transakcyjnym, to duża wygrana.
Innym dobrym kandydatem będącym przykładem problemu przekrojowego jest zezwolenie. Dodawanie adnotacji do metody usługi znacznikiem, który mówi, kto może ją wywołać, i pozwolenie niektórym poradom AOP zdecydować, czy zezwolić na wywołanie metody, czy nie, może być lepsze niż obsługa tego w kodzie metody usługi.
Wdrożenie rejestrowania z poradami AOP może być sposobem na uzyskanie większej elastyczności, dzięki czemu można zmienić to, co jest rejestrowane, zmieniając punkt złączenia. W praktyce nie widzę projektów, które tak często robią. Zwykle użycie biblioteki, takiej jak log4j, która umożliwia filtrowanie według poziomu logowania i kategorii, w czasie wykonywania, jeśli zajdzie taka potrzeba, działa wystarczająco dobrze.
Podstawowym problemem jest przyczyna istnienia aplikacji, logika biznesowa, którą aplikacja automatyzuje. Jeśli masz aplikację logistyczną, która obsługuje przewozy ładunków, kluczową kwestią może być ustalenie, ile ładunku można zapakować na ciężarówkę lub jaka jest najlepsza trasa, na którą samochód ciężarowy ma wysadzić swoje dostawy. Kwestie przekrojowe to zazwyczaj szczegóły dotyczące implementacji, które muszą być oddzielone od logiki biznesowej.
Tak więc, mimo że zachowanie transakcyjne tak naprawdę istnieje tylko w warstwie dostępu do danych, ponieważ bloki try-catch są powielane w wielu metodach, jest ono uważane za przekrojowe. Moje pierwotne wyobrażenie było takie, że przekrój poprzeczny oznaczał, że kod obejmował wiele warstw aplikacji.
jlars62
4
@ jlars62: przekrój poprzeczny oznacza, że przechodzi pod kątem prostym do elementów.
Nathan Hughes
7
@ jlars62: pod kątem prostym mam na myśli: pomyśl o funkcji jako stosie warstw. problem przekrojowy może dotyczyć tylko jednej warstwy, ale jest wspólny dla wszystkich elementów.
Nathan Hughes
Autoryzacja @NathanHughes jest dobrym przykładem. Właśnie zrekonstruowałem moją aplikację, aby umieścić cały kod autoryzacji w architekturze przekrojowej i zdziałało cuda, aby wyczyścić dużo kodu. Uważam tę domenę za dom. Jeśli masz klucz, aby się tam dostać, możesz tam robić, co chcesz (domniemywa się, że jesteś właścicielem). Ale nie zamknąłbyś wszystkich drzwi w domu i nie domagałbyś się klucza. Albo jesteś w środku, albo nie.
richard
„Zachowanie transakcyjne” może być typowe dla wielu funkcji, ale nie będzie to „przekrój poprzeczny”, ponieważ nie jest „przecinaniem” warstw. Powodem, na przykład, rejestrowanie jest problemem przekrojowym, ponieważ mogę chcieć zalogować się do warstwy prezentacji, warstwy biznesowej, warstwy danych itp.
CodingYoshi
14
Oprócz zaakceptowanej odpowiedzi chciałbym wspomnieć o innym przykładzie przekrojowego zagadnienia: zdalnej komunikacji. Powiedzmy, że chcę wywołać inne komponenty w moim ekosystemie lokalnie, tak jakby działały w trakcie. Może w niektórych przypadkach nawet to robią. Ale teraz chcę uruchamiać moje usługi rozproszone w chmurze lub klastrze. Dlaczego powinienem przejmować się tym aspektem jako twórca aplikacji? Aspekt może zająć się ustaleniem, do kogo i jak dzwonić, serializując przesyłane dane, jeśli to konieczne, i wykonując zdalne połączenie. Gdyby wszystko działało w trakcie, aspekt po prostu przekazywałby wywołanie lokalne. Po stronie odbierającej aspekt deserializuje dane, wykonuje wywołanie lokalne i zwraca wynik.
Pozwólcie, że opowiem wam teraz krótką historię o „trywialnych” rzeczach, takich jak wyjście dziennika: Zaledwie kilka tygodni temu zrefakturowałem złożoną, ale niezbyt dużą bazę kodu (około 250 tysięcy linii kodu) dla klienta. W kilkuset klasach używano jednego rodzaju struktury logowania, w kolejnych kilkuset innych. Potem było kilka tysięcy wierszySystem.out.println(*)gdzie naprawdę powinno być wyjście dziennika. Skończyło się na naprawieniu tysięcy linii kodu rozproszonych w bazie kodu. Na szczęście mogłem użyć sprytnych sztuczek w IntelliJ IDEA (strukturalne wyszukiwanie i zamiana), aby przyspieszyć całą akcję, ale nie sądzisz, że to było trywialne! Oczywiście, rejestrowanie debugowania silnie zależne od kontekstu zawsze będzie występować w treści metody, ale wiele ważnych typów rejestrowania, takich jak śledzenie wywołań metod (nawet hierarchicznie z ładnie wciętymi danymi wyjściowymi), rejestrowanie zarówno obsługiwanych, jak i nieobsługiwanych wyjątków, inspekcja użytkowników (rejestrowanie wywołań metody ograniczone oparte na rolach użytkowników) i tak dalej można łatwo zaimplementować w aspektach bez zanieczyszczania kodu źródłowego. Programista aplikacji na co dzień nie musi o tym myśleć, ani nawet widzieć wywołań rejestratora rozproszonych w bazie kodu.
Mogę wymyślić podobne wyjaśnienia dla innych przekrojowych problemów. Utrzymanie kodu w czystości i wolnego od rozpraszania i plątania IMO to kwestia profesjonalizmu, a nie niczego opcjonalnego. Wreszcie, co nie mniej ważne, utrzymuje kod czytelny, możliwy do utrzymania i refaktoryzacji. Amen.
Zagadnienia przekrojowe to scenariusze, które powinny zawsze występować niezależnie od rodzaju zastosowania.
Na przykład rejestrowanie, bezpieczeństwo, profilowanie wydajności, lokalizacja, dostępność, transakcja itp. Niezależnie od tworzonego przez nas oprogramowania wymagane jest rejestrowanie danych (w przeciwnym razie jak ktoś będzie debugował lub uzyska pewne istotne informacje z danych produktu). Bezpieczeństwo (uwierzytelnianie / autoryzacja itp.) Jest potrzebne, gdy tylko autentyczny użytkownik może wejść do aplikacji z odpowiednim zestawem uprawnień. Musimy wiedzieć, jak działa Twoja aplikacja, a następnie przeprowadzić profilowanie. W przypadku, gdy aplikacja jest używana przez użytkowników międzynarodowych (z własnym zlokalizowanym językiem), to musimy wspierać to samo w aplikacji. Dostępność to przypadki użyteczności dla osób niepełnosprawnych w korzystaniu z naszej aplikacji.
Teraz Niezależnie od tego, czy nasza aplikacja jest oparta na komputerach stacjonarnych, w Internecie itp., Jeśli ma być używana przez użytkowników końcowych w różnych lokalizacjach w środowisku produkcyjnym, potrzebne są przekroje poprzeczne. Do tej pory nie powiedziałem nic o tym, o co chodzi w aplikacji itp., Ale biorąc pod uwagę listę problemów, którymi należy się zająć przed udostępnieniem jej użytkownikom końcowym w środowisku produkcyjnym. i to wszystko dotyczy problemów z cięciami poprzecznymi (które muszą być obsługiwane przez wszystkie aplikacje / metody / klasy, tj. na różnych poziomach).
Myślę, że najlepszym przykładem przekrojowego problemu jest zachowanie transakcyjne. Na przykład konieczność umieszczania bloków try-catch z wywołaniami commit i rollback we wszystkich metodach usług byłaby odstraszająca. Oznaczanie metod znacznikiem, którego AOP może użyć do hermetyzacji ich pożądanym zachowaniem transakcyjnym, to duża wygrana.
Innym dobrym kandydatem będącym przykładem problemu przekrojowego jest zezwolenie. Dodawanie adnotacji do metody usługi znacznikiem, który mówi, kto może ją wywołać, i pozwolenie niektórym poradom AOP zdecydować, czy zezwolić na wywołanie metody, czy nie, może być lepsze niż obsługa tego w kodzie metody usługi.
Wdrożenie rejestrowania z poradami AOP może być sposobem na uzyskanie większej elastyczności, dzięki czemu można zmienić to, co jest rejestrowane, zmieniając punkt złączenia. W praktyce nie widzę projektów, które tak często robią. Zwykle użycie biblioteki, takiej jak log4j, która umożliwia filtrowanie według poziomu logowania i kategorii, w czasie wykonywania, jeśli zajdzie taka potrzeba, działa wystarczająco dobrze.
Podstawowym problemem jest przyczyna istnienia aplikacji, logika biznesowa, którą aplikacja automatyzuje. Jeśli masz aplikację logistyczną, która obsługuje przewozy ładunków, kluczową kwestią może być ustalenie, ile ładunku można zapakować na ciężarówkę lub jaka jest najlepsza trasa, na którą samochód ciężarowy ma wysadzić swoje dostawy. Kwestie przekrojowe to zazwyczaj szczegóły dotyczące implementacji, które muszą być oddzielone od logiki biznesowej.
źródło
Oprócz zaakceptowanej odpowiedzi chciałbym wspomnieć o innym przykładzie przekrojowego zagadnienia: zdalnej komunikacji. Powiedzmy, że chcę wywołać inne komponenty w moim ekosystemie lokalnie, tak jakby działały w trakcie. Może w niektórych przypadkach nawet to robią. Ale teraz chcę uruchamiać moje usługi rozproszone w chmurze lub klastrze. Dlaczego powinienem przejmować się tym aspektem jako twórca aplikacji? Aspekt może zająć się ustaleniem, do kogo i jak dzwonić, serializując przesyłane dane, jeśli to konieczne, i wykonując zdalne połączenie. Gdyby wszystko działało w trakcie, aspekt po prostu przekazywałby wywołanie lokalne. Po stronie odbierającej aspekt deserializuje dane, wykonuje wywołanie lokalne i zwraca wynik.
Pozwólcie, że opowiem wam teraz krótką historię o „trywialnych” rzeczach, takich jak wyjście dziennika: Zaledwie kilka tygodni temu zrefakturowałem złożoną, ale niezbyt dużą bazę kodu (około 250 tysięcy linii kodu) dla klienta. W kilkuset klasach używano jednego rodzaju struktury logowania, w kolejnych kilkuset innych. Potem było kilka tysięcy wierszy
System.out.println(*)
gdzie naprawdę powinno być wyjście dziennika. Skończyło się na naprawieniu tysięcy linii kodu rozproszonych w bazie kodu. Na szczęście mogłem użyć sprytnych sztuczek w IntelliJ IDEA (strukturalne wyszukiwanie i zamiana), aby przyspieszyć całą akcję, ale nie sądzisz, że to było trywialne! Oczywiście, rejestrowanie debugowania silnie zależne od kontekstu zawsze będzie występować w treści metody, ale wiele ważnych typów rejestrowania, takich jak śledzenie wywołań metod (nawet hierarchicznie z ładnie wciętymi danymi wyjściowymi), rejestrowanie zarówno obsługiwanych, jak i nieobsługiwanych wyjątków, inspekcja użytkowników (rejestrowanie wywołań metody ograniczone oparte na rolach użytkowników) i tak dalej można łatwo zaimplementować w aspektach bez zanieczyszczania kodu źródłowego. Programista aplikacji na co dzień nie musi o tym myśleć, ani nawet widzieć wywołań rejestratora rozproszonych w bazie kodu.Mogę wymyślić podobne wyjaśnienia dla innych przekrojowych problemów. Utrzymanie kodu w czystości i wolnego od rozpraszania i plątania IMO to kwestia profesjonalizmu, a nie niczego opcjonalnego. Wreszcie, co nie mniej ważne, utrzymuje kod czytelny, możliwy do utrzymania i refaktoryzacji. Amen.
źródło
Zagadnienia przekrojowe to scenariusze, które powinny zawsze występować niezależnie od rodzaju zastosowania.
Na przykład rejestrowanie, bezpieczeństwo, profilowanie wydajności, lokalizacja, dostępność, transakcja itp. Niezależnie od tworzonego przez nas oprogramowania wymagane jest rejestrowanie danych (w przeciwnym razie jak ktoś będzie debugował lub uzyska pewne istotne informacje z danych produktu). Bezpieczeństwo (uwierzytelnianie / autoryzacja itp.) Jest potrzebne, gdy tylko autentyczny użytkownik może wejść do aplikacji z odpowiednim zestawem uprawnień. Musimy wiedzieć, jak działa Twoja aplikacja, a następnie przeprowadzić profilowanie. W przypadku, gdy aplikacja jest używana przez użytkowników międzynarodowych (z własnym zlokalizowanym językiem), to musimy wspierać to samo w aplikacji. Dostępność to przypadki użyteczności dla osób niepełnosprawnych w korzystaniu z naszej aplikacji.
Teraz Niezależnie od tego, czy nasza aplikacja jest oparta na komputerach stacjonarnych, w Internecie itp., Jeśli ma być używana przez użytkowników końcowych w różnych lokalizacjach w środowisku produkcyjnym, potrzebne są przekroje poprzeczne. Do tej pory nie powiedziałem nic o tym, o co chodzi w aplikacji itp., Ale biorąc pod uwagę listę problemów, którymi należy się zająć przed udostępnieniem jej użytkownikom końcowym w środowisku produkcyjnym. i to wszystko dotyczy problemów z cięciami poprzecznymi (które muszą być obsługiwane przez wszystkie aplikacje / metody / klasy, tj. na różnych poziomach).
źródło