Programowanie zorientowane na aspekty obiecuje rozwiązywać problemy przekrojowe, ale nie jestem jeszcze w pełni sprzedany. Czy były jakieś inne próby rozwiązania tego problemu?
paradigms
aspect-oriented
Casebash
źródło
źródło
Odpowiedzi:
Jeśli to możliwe, możesz zamknąć zagadnienia przekrojowe w osobne moduły, które są następnie używane w aplikacji poprzez wstrzykiwanie zależności. Pozwala to nieco oddzielić implementację problematyki przekrojowej od jej wykorzystania w całym kodzie.
Jednak nie zawsze działa to elegancko. To jest powód, dla którego ludzie próbują rozwiązać ten problem za pomocą AOP.
źródło
Dwie inne opcje, których jeszcze nie widziałem:
Programowanie funkcjonalne za pomocą monad i strzałek
W FP reprezentujesz problem przekrojowy jak wszystko inne: jako coś, co przekazujesz w wywołaniu funkcji. Ponieważ robienie tego wyraźnie staje się nużące, możesz użyć Monad (lub strzałek), aby ukryć dodatkowe przekazywane informacje.
Najczęstszym przykładem AOP jest rejestrowanie. W Monadach stworzyłbyś monadę „Logger”, która przechowuje listę wiadomości. Wszelkie funkcje wykonywane przez LoggerMonad mają możliwość publikowania wiadomości dziennika. Za pomocą Arrows można modelować cały przepływ danych aplikacji i w razie potrzeby uruchamiać procedurę rejestrowania w modelu. Myślę. Strzały są dość złożone.
Programowanie oparte na jednostkach / komponentach
Coś, z czym badałem i eksperymentowałem dla silnika gry. Zamiast „obiektów”, jak w OOP, rozkładasz wszystko na pakiety danych (komponentów) i usług, które działają na danym typie komponentu. Komponenty są pogrupowane według wspólnych identyfikatorów, np. W relacyjnej bazie danych, a grupy połączonych komponentów to Encje. Aby dodać rejestrowanie w takim systemie, należy dodać nową usługę rejestrowania wyzwalaczy, w oparciu o które składniki są przez nią przekazywane.
Obie metody pozwalają na łatwą pracę nad przekrojową zmianą, ale oba są wysokopoziomowymi modelami architektonicznymi. Prawdopodobnie będziesz musiał ich używać od samego początku. Model Component można teoretycznie przerobić na istniejący system OOP. Myślę, że monady też mogą być, jeśli twój język jest wystarczająco silny.
źródło
Istnieje kilka sposobów rozwiązania problemów związanych z przekrojami:
Używaj lepszych wzorców projektowych, idiomów lub mechanizmów abstrakcyjnych : kod może być przekrojowy, nawet jeśli można go zmodularyzować. Aby zachować kod, konieczne będzie refaktoryzacja w celu zastosowania techniki projektowania, która może go modulować. Takie refaktoryzacja może wprowadzać inny rodzaj przekrojów, ale miejmy nadzieję, że takie przekroje są stabilne i raczej nie zmienią się.
Rozwijaj bogatsze funkcje językowe : Wiele przejawów przekrojów można rozwiązać za pomocą lepszych mechanizmów abstrakcyjnych, a czasem konieczne są nowe funkcje językowe. Na przykład bardziej zaawansowane języki, które zawierają funkcje funkcjonalne i obiektowe, często nie wykorzystują tylu wzorców projektowych, ponieważ nie są konieczne. Zauważ, że same wzorce projektowe mogą mieć charakter przekrojowy , ponieważ opisują role kilku różnych obiektów i klas. W Javie często można zastosować odbicie zamiast aspektu, chociaż wiąże się to z wyższymi kosztami środowiska wykonawczego. Na przykład za pomocą odbicia możesz wesprzeć wzorzec odwiedzających w setkach klas za pomocą zaledwie kilku wierszy kodu. Biblioteka DJ-az Northeastern to jedno odblaskowe rozwiązanie, które właśnie to robi. Miksy są potężną techniką dostępną w C ++ (ale nie Java) i mogą dać ci te same przypadki użycia jako aspekt.
Zapewnij lepszą obsługę narzędzi : techniki takie jak używanie
grep
i przeprowadzanie operacji refaktoryzacji mogą rozwiązać problemy związane z kodem przekrojowym. Na przykład nazwa metody zadeklarowanej w interfejsie może przecinać program. (Zwróć uwagę na różnicę techniczną tutaj: to nazwa metody, a nie jej implementacja, to przekroje.) Zazwyczaj nie jest to problem w środowisku IDE, takim jak Eclipse, w którym można użyć „zmiany nazwy refaktoryzacji”, aby zmienić wszystkie miejsca w kodzie, które używają nazwy. W ten sposób można nie potrzebować funkcji językowych, gdy środowisko programistyczne jest dla Ciebie wystarczająco wyraziste.Używaj języków specyficznych dla domeny : wczesne języki aspektów, które pojawiły się przed AspectJ, były specyficzne dla domeny i stosowane tylko w niektórych problemach, takich jak synchronizacja wątków lub analiza przepływu danych w celu skutecznego łączenia kompozycji funkcji. Te języki były eksperymentalne, ale wydawały się bardzo skuteczne w modularyzacji problemów, które w przeciwnym razie byłyby przekrojowe.
Użyj technik programowania generatywnego : Awans do poziomu meta może być uważany za technikę implementacji programowania aspektowego, ale jest to wystarczająco duży obszar, że wykracza poza proste aspekty. Techniki generacyjne (w których program generuje kod źródłowy dla innego programu) są również powiązane z językami specyficznymi dla domeny.
W przypadku wszystkich tych przypadków uważam, że studiowanie AOP jest właściwe. AOP może pomóc rozwinąć twoje koncepcje kodu, nawet jeśli nie używasz języka AOP.
źródło
Ogólnie tagowanie elementów kodu z funkcją deklaratywną, ale konkretnie systemem atrybutów w świecie C # / .NET / Mono.
źródło
Nie jestem ekspertem od AOP, ale czytając o tym przez lata, zawsze wydawało się to słabszą formą metaprogramowania oferowaną przez Lisp , szczególnie części takich jak protokół metaobiektu.
Nie powinno to dziwić, jak sądzę: Gregor Kiczales był jednym z autorów AMOP, a później napisał AspectJ dla Javy!
źródło