Są pewne problemy rozwiązać bardziej elegancko z AOP?

19

Natknąłem się na programowanie aspektowe i mam z tym pewne obawy.

Podstawowa idea wydaje się, że chcemy wziąć obawy przekrojowe, które nie są dobrze zmodularyzowany użyciem obiektu i zmodularyzowanie im. To wszystko bardzo dobrze i dobrze.

Ale realizacja AOP wydaje się, że do modyfikowania kodu z zewnątrz modułu. Tak więc, na przykład, aspekt może być napisane, że zmiany, co się dzieje, gdy dany obiekt zostanie przekazany jako parametr funkcji. Wydaje się, aby przejść bezpośrednio przed ideą modułów. I nie powinien być w stanie modyfikować zachowanie modułu jest spoza tego modułu, w przeciwnym razie cały punkt modułów są przewrócone. Ale aspekty wydają się być właśnie to robi!

Zasadniczo aspekty wydają się być formą łatania kodu. Może się przydać przy szybkich włamaniach; ale ogólną zasadą może nie jest to, że chcesz to zrobić. Programowanie zorientowane na aspekt wydaje mi się przyjmować złą praktykę i przejść do ogólnej zasady projektowania.

Czy AOP to dobra praktyka? Czy niektóre problemy programistyczne rozwiązuje się bardziej elegancko dzięki AOP?

Winston Ewert
źródło
ahhh, słynna łatka małpy!
Muad'Dib
1
Mam edytowane pytanie do poprawy jej koloryt, a głosowanie ponowne otwarcie.
Robert Harvey
Questio został również ponownie poproszony w innej formie tutaj: programmers.stackexchange.com/questions/19344/…
Peter Boughton

Odpowiedzi:

19

Programowanie zorientowane na aspekty umożliwia wykonywanie pewnych rodzajów programowania, które są trudne do wykonania bez niepotrzebnego rozpraszania kodu w całej aplikacji lub bibliotece niezwiązanej z podstawowymi funkcjami oprogramowania (tj. Problemami przekrojowymi). Przykłady zawierają:

  1. Rejestrowanie i monitorowanie
  2. Analiza wydajności
  3. Debugowanie i śledzenie
  4. Cofnij funkcjonalność
  5. Walidacja wejść i wyjść
  6. Morphing zachowanie istniejących obiektów
  7. Filtry obiektowe
  8. Implementacja zabezpieczeń
  9. zarządzania transakcjami

Ograniczając takie przekrojowe obawy do jednej części aplikacji, a następnie odwołując się do tych funkcji w kodzie za pomocą atrybutów, przechwytywania wywołań metod lub dynamicznych serwerów proxy, pozwalasz na enkapsulację zachowania przekrojowego; To wszystko z korzyści (czyli jeden punkt modyfikacja) hermetyzacja dawałaby nigdzie indziej w aplikacji.

Kluczową kwestią jest to, że zachowanie to jest AOP obudowuje 1) wspólne całej aplikacji, oraz 2) obwodowych do podstawowej funkcjonalności aplikacji.

Robert Harvey
źródło
7

Spóźnię się do gry, ale zapewniam ją późniejszym programistom, którzy mogą natknąć się na to pytanie.

Zdecydowanie odradzam AOP jeśli aplikacja zależy na tym, aby działać poprawnie. Aspekty działa tak:

  • Rada (dodatkowy zachowanie) jest stosowany do
  • Dołącz punkty (miejsca, w których można dołączyć dodatkowy kod, taki początek lub koniec metoda A lub gdy dana wyzwalaczy zdarzeń)
  • ... gdzie punktu przekroju (wzór, który wykrywa, czy dany punkt) dołączyć mecze dopasować wzory

Dla każdego, kto robi komputerów przez długi czas, fakt, że wzorce są wykorzystywane mogą być na co patrzeć uważnie. Więc tutaj jest przykład punkt przekroju, który odpowiada żadnej metody o nazwie setniezależnie od argumentów:

call(* set(..))

Jest to więc dość obszerny punkt zwrotny i powinno być jasne, że radzenie sobie z tym ostrożnie jest zalecane (bez zamierzonej gry słów), ponieważ stosuje się porady do wielu rzeczy.

Lub cholery, niech stosuje porad wszystkim , bez względu na nazwę lub podpis!

execution(* *(..))

Widać więc, że powinniśmy być ostrożni, bo nie ma dużo energii tutaj, ale to nie jest argument przeciwko aspektach - to argument za ostrożnością, ponieważ jest tam dużo energii tutaj i dopasowywanie do wzorca można łatwo przejść na opak (tylko uderzyć swoją ulubioną wyszukiwarkę AOP błędy i zabawy).

Więc oto co wygląda stosunkowo bezpiecznego punktu przekroju:

pointcut setter(): target(Point) &&
                   ( call(void setX(int)) ||
                     call(void setY(int)) );

Który wyraźnie stanowi porady jeśli metody nazwie setXlub setYna Pointobiekcie znajdują. Metody te mogą otrzymać tylko intS i muszą byćvoid . Wygląda całkiem bezpiecznie, prawda? Dobrze, że to bezpieczne, jeśli istnieją takie metody i masz zastosowano właściwą poradę. Jeśli nie, to źle; po cichu zawodzi.

Na przykład przyjaciel próbował debugować aplikację Java, w której wszyscy raz na jakiś czas zwracali nieprawidłowe dane. To była rzadka awaria i nie wydawała się być skorelowana z żadnym konkretnym zdarzeniem lub konkretnymi danymi. To był błąd, gwintowania, coś, co jest bardzo trudne do pomiaru lub wykrywania. Jak się okazuje, używali aspektów do blokowania metod i uczynienia ich „bezpiecznymi dla wątków”, ale programista zmienił nazwę metody i punkt nie pasował do niej, powodując w ten sposób cichą awarię aplikacji.

Dlatego mówię ludziom, że jeśli muszą używać AOP, do traktowania aspektów takich jak wyjątki: w dobrze zaprojektowanym systemie i jeśli nic nie pójdzie źle, można je usunąć, a oprogramowanie nadal działa poprawnie. Jeśli jednak funkcjonalność programu zależy od AOP, wprowadzasz do programu niestabilność, która jest nieuzasadniona.

Zatem rejestrowanie, debugowanie i śledzenie są świetnymi przykładami zachowań, które są idealne pod względem aspektów, ale bezpieczeństwa? Nie. Bezpieczeństwo wątku? Nie.

Dla solidnej alternatywy dla AOP patrz cechy . Zamiast być przymocowanym do języka, są one zintegrowane z nim bezpośrednio, nie potrzebują IDE „rozpoznającego cechy” (choć może to pomóc) i mają błędy w czasie kompilacji, jeśli wymagane metody nie są obecne. Cechy wykonują znacznie czystszą pracę w rozwiązywaniu problemów, ponieważ problem był lepiej definiowany od samego początku. Używam ich dużo i są fantastyczne.

Curtis Poe
źródło
Zamiast argumentować, że AOP nie należy używać do podstawowej funkcjonalności, bardziej odpowiednie może być stwierdzenie, że skróty punktowe oparte na nazwach metod są złym pomysłem. Pewnie bym twierdzą, że blokowanie i synchronizacja nie są dobre dla przypadków użycia AOP, albo.
Kod Bling
2

Jedna sytuacja, w której AOP może być jedynym przyzwoitym, jak również praktycznym rozwiązaniem jest , gdy nie ma dostępu do kodu źródłowego . Aby użyć zniszczony stary przykład troski Logging przekrojowy:

Załóżmy, że chcesz zarejestrować przepływ kontroli w używanej przez siebie bibliotece innej firmy. Masz własny kod w pełni wyposażony w instrukcje rejestrowania. Jednak dla tej biblioteki nie masz źródła, co uniemożliwia dodanie instrukcji rejestrowania. Ponieważ zrobić mają kodu bajtowego, AOP pozwala na instrument, który w każdym razie biblioteki strona trzecia.

A jeśli tworzysz aspekt rejestrowania tak, równie dobrze można rozważyć wdrożenie Logging z AOP troughout własnego kodu, jak również.

Joseph Tanenbaum
źródło
Rejestrowanie jest „ciekawe” rzeczy. Jak można robić inne rzeczy niż „wchodzi z tych parametrów” i „wyjściu” z logowaniem AOP?
@Thorbjorn: Rejestrowanie / debugowanie / śledzenie to tylko jeden z wielu obszarów funkcjonalności, w których AOP może pomóc. Używałem go jako przykład, aby zilustrować mój punkt widzenia. Punkt staram się zrobić to, że AOP daje większą kontrolę nad trzecim kodu bajtowego partii.
Joseph Tanenbaum
Jasne, ale ja naprawdę chciał wiedzieć, czy rejestrowanie AOP może zrobić więcej niż wejść-wyjść tylko logowania?
Zależy to od używanego narzędzia AOP, ale z pewnością istnieją granice tego, co możesz zrobić. Bardzo możliwe może być wyjście poza rejestrowanie wejść-wyjść.
Joseph Tanenbaum,