Ostatnio zacząłem myśleć, że posiadanie wielu klas menedżerskich w twoim projekcie jest złe. Pomysł nie jest wystarczająco dojrzały, aby przedstawić przekonujący argument, ale oto kilka ogólnych kwestii:
Odkryłem, że dużo trudniej mi zrozumieć systemy, które w dużym stopniu opierają się na „menedżerach”. Wynika to z faktu, że oprócz rzeczywistych składników programu należy również zrozumieć, w jaki sposób i dlaczego używany jest menedżer.
Menedżerowie często wydają się być wykorzystywani do łagodzenia problemu z projektem, na przykład gdy programista nie mógł znaleźć sposobu na uczynienie programu Just Work TM i musiał polegać na klasach menedżerów, aby wszystko działało poprawnie.
Oczywiście menedżerowie mogą być dobrzy. Oczywistym przykładem jest EventManager
jedna z moich ulubionych konstrukcji. : P Chodzi mi o to, że menedżerowie wydają się być nadużywani przez większość czasu i nie bez innego powodu niż maskowanie problemu z architekturą programu.
Czy klasy menedżerskie są naprawdę oznaką złej architektury?
źródło
Of course, mangers can be good. An obvious example is an EventManager
to wszystko wyjaśnia. Niewłaściwe użycie tej koncepcji to zła architektura, ale istnieją uzasadnione przypadki użycia. To samo dotyczy większości czegokolwiek.EventManager
to okropne imię dla klasy. Pozornie robi coś ze zdarzeniami, ale co ?Odpowiedzi:
Klasy menedżerów mogą być oznaką złej architektury z kilku powodów:
Bez znaczenia identyfikatory
Nazwa
FooManager
nie mówi nic o tym, co faktycznie robi klasa , poza tym, że w jakiś sposób obejmuje onaFoo
instancje. Nadanie klasie bardziej znaczącej nazwy wyjaśnia jej prawdziwy cel, który prawdopodobnie doprowadzi do refaktoryzacji.Obowiązki ułamkowe
Zgodnie z zasadą jednej odpowiedzialności, każda jednostka kodu powinna służyć dokładnie jednemu celowi. Z menedżerem możesz sztucznie dzielić tę odpowiedzialność.
Rozważ taki,
ResourceManager
który koordynuje czasy życia i dostęp doResource
instancji. Aplikacja ma jeden,ResourceManager
przez który nabywaResource
instancje. W tym przypadku nie ma prawdziwego powodu, dla którego funkcjaResourceManager
instancji nie może być obsługiwana przez metody statyczne wResource
klasie.Abstrakcja nieustrukturyzowana
Często wprowadza się menedżera, aby pozbyć się podstawowych problemów z obiektami, którymi zarządza. Właśnie dlatego menedżerowie dopuszczają się nadużyć jako pomocników dla źle zaprojektowanych systemów. Abstrakcja jest dobrym sposobem na uproszczenie złożonego systemu, ale nazwa „menedżer” nie daje żadnych wskazówek co do struktury reprezentowanej przez nią abstrakcji. Czy to naprawdę fabryka, proxy, czy coś innego?
Oczywiście, menedżerowie mogą być wykorzystywani do czegoś więcej niż tylko zła, z tych samych powodów. „Co
EventManager
tak naprawdę jest” -Dispatcher
porządkuje zdarzenia ze źródeł i kieruje je do zainteresowanych celów. W takim przypadku sensowne jest oddzielenie odpowiedzialności za przyjmowanie i wysyłanie zdarzeń, ponieważ osobaEvent
jest tylko wiadomością bez pojęcia pochodzenia lub przeznaczenia.Piszemy
Dispatcher
oEvent
instancjach z tego samego powodu, dla którego piszemy aGarbageCollector
lub aFactory
:Menedżer wie, czego nie powinien wiedzieć jego ładunek.
Myślę, że to najlepsze uzasadnienie dla stworzenia klasy menedżerskiej. Kiedy masz jakiś „ładunek”, który zachowuje się jak wartość, powinien być tak głupi, jak to możliwe, aby cały system pozostał elastyczny. Aby nadać znaczenie poszczególnym instancjom, należy utworzyć menedżera, który koordynuje te instancje w znaczący sposób. W każdej innej sytuacji menedżerowie są niepotrzebni.
źródło
EventDispatcher
jakiegoś czasu próbowałem znaleźć dobre imię. : PMenedżerowie mogą być oznaką złej architektury, ale najczęściej są tylko oznaką niezdolności projektanta do wymyślenia lepszych nazw dla swoich obiektów lub po prostu odzwierciedleniem faktu, że język angielski (i jakikolwiek ludzki język w tym zakresie) nadaje się do komunikowania codziennych praktycznych pojęć, a nie wysoce abstrakcyjnych, wysoce technicznych pojęć.
Prosty przykład ilustrujący mój punkt widzenia: zanim nazwano Wzorzec Fabryczny , ludzie go używali, ale nie wiedzieli, jak go nazwać. Więc ktoś, kto musiał napisać fabrykę dla swojej
Foo
klasy, mógł to nazwaćFooAllocationManager
. To nie jest zły projekt, to po prostu brak wyobraźni.A potem ktoś musi wdrożyć klasę, która utrzymuje wiele fabryk i przekazuje je różnym przedmiotom, które o nie proszą; i woła swoją klasę,
FactoryManager
ponieważ to słowoIndustry
nigdy nie przyszło mu do głowy, lub pomyślał, że byłoby to niefajne, ponieważ nigdy wcześniej nie słyszał o czymś takim w programowaniu. Znów przypadek braku wyobraźni.źródło
Posiadanie wielu klas „menedżerskich” jest często objawem anemicznego modelu domeny , w którym logika domeny jest wyciągana z modelu domeny i zamiast tego umieszczana w klasach menedżerów, które mniej więcej odpowiadają skryptom transakcyjnym . Niebezpieczeństwo polega na tym, że w zasadzie powracasz do programowania proceduralnego - które samo w sobie może, ale nie musi być dobrą rzeczą w zależności od twojego projektu - ale fakt, że nie został wzięty pod uwagę ani zamierzony, jest prawdziwym problemem imo.
Zgodnie z zasadą „eksperta ds. Informacji” operacja logiczna powinna znajdować się jak najbliżej wymaganych danych. Oznaczałoby to przeniesienie logiki domeny z powrotem do modelu domeny, dzięki czemu te logiczne operacje mają zauważalny wpływ na stan modelu domeny, a nie „menedżerów” zmieniających stan modelu domeny z zewnątrz.
źródło
Krótka odpowiedź: to zależy .
Istnieje kilka różnych form „klas menedżerów”, niektóre z nich są dobre, inne są złe, a dla większości z nich wiele zależy od kontekstu, czy wprowadzenie klasy menedżera jest właściwe. Dobrym punktem wyjścia do ich poprawnego działania jest przestrzeganie zasady pojedynczej odpowiedzialności - jeśli dokładnie wiesz, za co odpowiada każda z twoich klas menedżerskich (a co nie), będziesz mieć znacznie mniej problemów ze zrozumieniem ich.
Lub bezpośrednio odpowiedzieć na twoje pytanie: nie jest to liczba klas menedżerów wskazujących na złą architekturę, ale posiadanie zbyt wielu z niejasnych obowiązków lub zajmowanie się zbyt wieloma problemami.
źródło
Chociaż łatwo jest powiedzieć, że z natury wskazują na zły projekt, mogą one przynieść wiele dobrego i zmniejszyć złożoność kodu oraz inne kody wzorcowe w całym projekcie, obejmując jedno zadanie i odpowiedzialność uniwersalnie.
Chociaż występowanie menedżerów może wynikać z niewłaściwej oceny projektu, mogą one również zajmować się złymi decyzjami projektowymi lub problemami z niekompatybilnością z innymi komponentami w komponentowym projekcie lub komponentami interfejsu użytkownika innych firm, lub usługami internetowymi stron trzecich o dziwnym interfejsie jako przykłady.
Te przykłady pokazują, gdzie są one szczególnie przydatne w pewnych sytuacjach w zmniejszaniu ogólnej złożoności i promowaniu luźnego łączenia różnych komponentów i warstw poprzez kapsułkowanie „brzydkiego kodu” w jednym miejscu. Jedną z rzeczy byłoby to, że ludzie uważają za kuszące uczynienie Menedżerów singlami, odradzałbym to i oczywiście, ponieważ inni sugerowali, że należy zawsze przestrzegać zasady pojedynczej odpowiedzialności.
źródło
Odpowiedziałeś na swoje pytanie: nie muszą być oznaką złego projektu.
Oprócz przykładu w pytaniu z EventManager istnieje jeszcze inny przykład: we wzorcu projektowym MVC , prezenter może być postrzegany jako menedżer dla klas modelu / widoku.
Jeśli jednak źle wykorzystasz koncepcję, jest to znak złego projektu i być może architektury.
źródło
Gdy klasa ma w nazwie „Menedżera”, strzeż się problemu z boską klasą (jeden ze zbyt wieloma obowiązkami). Jeśli trudno jest opisać, za co klasa jest odpowiedzialna swoją nazwą, jest to znak ostrzegawczy projektu.
Poza złymi klasami menedżerów, najgorsze imię, jakie kiedykolwiek widziałem, to „DataContainerAdapter”
„Dane” powinny być kolejnym z zabronionych podciągów w nazwach - to wszystkie dane, „dane” nie mówią zbyt wiele w większości domen.
źródło
Klasy menedżerskie - podobnie jak prawie każda klasa kończąca się na „-er” - są złe i nie mają nic wspólnego z OOP. Dla mnie to oznaka złej architektury.
Dlaczego? Nazwa „-er” oznacza, że projektant kodu podjął pewne działania i przekształcił go w klasę. W rezultacie mamy sztuczną istotę, która nie odzwierciedla żadnej namacalnej koncepcji, ale pewne działanie. Brzmi to bardzo proceduralnie.
Poza tym zwykle takie klasy pobierają pewne dane i działają na nich. Jest to filozofia pasywnych danych i aktywnych procedur, która znalazła swoje miejsce w programowaniu proceduralnym. Jeśli zdasz sobie z tego sprawę, nie ma nic złego w klasach Menedżera, ale wtedy nie jest to OOP.
Myślenie obiektowe implikuje, że przedmioty robią sobie same. Odkryj swoją domenę , buduj sieci semantyczne , pozwól swoim obiektom być żywymi organizmami, inteligentnymi i odpowiedzialnymi ludźmi.
Takich obiektów nie trzeba kontrolować. Wiedzą, co robić i jak to zrobić. Tak więc klasy menedżerów dwukrotnie łamią zasady OOP. Poza tym, że jest klasą „-er”, kontroluje inne obiekty. Ale to zależy od menedżera. To kontroluje - jest złym menedżerem. Jeśli koordynuje - jest dobrym menedżerem. Dlatego litera „C” w MVC powinna być pisana jako „Koordynator”.
źródło
Prawidłowa odpowiedź na to pytanie brzmi:
Każda sytuacja, z którą napotkasz podczas pisania oprogramowania, jest inna. Może jesteś w zespole, w którym wszyscy wiedzą, jak działają klasy menedżerskie? Byłoby całkowicie szalone, gdyby nie używać tego projektu. Lub jeśli próbujesz przekazać projekt menedżera innym osobom, w takim przypadku może to być zły pomysł. Ale zależy to od dokładnych szczegółów.
źródło