Czy klasy menedżerskie mogą być oznaką złej architektury?

49

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 EventManagerjedna 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?

Paweł
źródło
5
Myślę, że Of course, mangers can be good. An obvious example is an EventManagerto 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.
27
Bardziej prawdopodobne jest, że będzie to znak bez wyobraźni.
pdr
9
EventManagerto okropne imię dla klasy. Pozornie robi coś ze zdarzeniami, ale co ?
Christoffer Hammarström
5
jednym z problemów tutaj jest ograniczenie językowe steve-yegge.blogspot.com/2006/03/... Klasy menedżerskie są często spowodowane przez czasowniki nounifikujące, naprawdę potrzebne są wolne funkcje
jk.
1
Menedżerowie często mają dużą władzę (obowiązki) i mogą być uciążliwe - tak jak w każdym środowisku biurowym;) EventManager nic nie znaczy. EventDispatcher opisuje, co robi.
CodeART

Odpowiedzi:

31

Klasy menedżerów mogą być oznaką złej architektury z kilku powodów:

  • Bez znaczenia identyfikatory

    Nazwa FooManagernie mówi nic o tym, co faktycznie robi klasa , poza tym, że w jakiś sposób obejmuje ona Fooinstancje. 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, ResourceManagerktóry koordynuje czasy życia i dostęp do Resourceinstancji. Aplikacja ma jeden, ResourceManagerprzez który nabywa Resourceinstancje. W tym przypadku nie ma prawdziwego powodu, dla którego funkcja ResourceManagerinstancji nie może być obsługiwana przez metody statyczne w Resourceklasie.

  • 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 EventManagertak naprawdę jest” - Dispatcherporzą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ż osoba Eventjest tylko wiadomością bez pojęcia pochodzenia lub przeznaczenia.

Piszemy Dispatchero Eventinstancjach z tego samego powodu, dla którego piszemy a GarbageCollectorlub a Factory:

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.

Jon Purdy
źródło
3
Zdecydowanie wcześniej tworzyłem klasy FooManager. Stworzyłem również fabryki i proxy. Ale czasami wydaje się, że naprawdę potrzebujesz typu GlorifiedCollection <Foo>, a FooManager wydaje się idealnie pasować do rachunku. Jak nazwałbyś klasę, która dosłownie zarządza wewnętrzną kolekcją obiektów Foo i zapewnia bardzo czysty i zwięzły interfejs do pobierania instancji Foo? Myślę, że „manager” to klasa, która zawiera w sobie fabrykę (tzn. Wszystkie instancje Foo są inicjowane wewnętrznie), a także zbiór tych obiektów. Nazwałbyś to czymś innym? Czy zrobić inny projekt?
DXM,
Ach tak, od EventDispatcherjakiegoś czasu próbowałem znaleźć dobre imię. : P
Paul
@DXM Dla kolekcji Foos może to być dosłownie „FooList”. W przypadku globalnego miejsca, w którym Foos są rejestrowane i można je później odzyskać, przychodzi na myśl „FooRegistry”. Łączenie kolekcji i fabryki nie jest czymś, co osobiście lubię, ale wierzę, że zwykle nazywa się to „FooRepository”.
R. Schmitz
28

Menedż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 Fooklasy, 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ę, FactoryManagerponieważ to słowo Industrynigdy 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.

Mike Nakis
źródło
10

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.

MattDavey
źródło
8

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.

Doktor Brown
źródło
Niestety nie uważam tej odpowiedzi za bardzo przydatną. Masz rację, że niejasne obowiązki i zbyt wiele obaw są złe. Ale dotyczy to każdej klasy , nie tylko klasy „Manager”. Inne odpowiedzi wydają się znacznie bardziej szczegółowe na temat tego, w jaki sposób klasa menedżerska może być pomocna lub szkodliwa.
user949300,
3

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.

wałek klonowy
źródło
2

Czy klasy menedżerskie mogą być oznaką złej architektury?

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.

BЈовић
źródło
W treści pytania - „posiadanie wielu klas menedżerskich w twoim projekcie to zła rzecz”. Uważam, że to właśnie OP chce naprawdę wiedzieć.
Oded
2

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.

zaraz
źródło
2

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”.

Zapadło
źródło
Robisz interesujący punkt, ale wciąż zastanawiam się, jak sklasyfikowałbyś „menedżera podmiotu”? Z mojego osobistego doświadczenia, menedżer <entity> jest przeznaczony do operacji CRUD na określonym <entity>. Czy prowadzi to do anemii modelu domeny? Nie sądzę, tylko nie „aktywny rekord”. Co więcej, czy nie możemy wprowadzić logiki koordynacji CRUD „podmiotu zarządzającego” podmiotem? Nie widzę lepszego miejsca na to. Może to być w jakiś sposób postrzegane jako fasada CRUD ...
ClemC,
Wszystko, co mogę powiedzieć o
koncepcji
Nie musiałem jednak odwoływać się do ORM, ale ... szanuję jak najwięcej zasad OO, ale wydaje mi się, że są one dość teoretyczne i nie zawsze mogą być w pełni stosowane w praktyce ... Na przykład, jeśli potrzebujemy oddzielenia, ponownego użycia, OSUSZANIA, produktywności, np .: umieszczenie logiki / reguł domeny, które mają zastosowanie do różnych podmiotów we wspólnych usługach, a tym samym uczynienie modelu domeny mniej behawioralnym ... To jest dokładnie efekt wzorca repozytorium / mapera (który ORM ty zobacz implementację) VS aktywny wzorzec zapisu, który, jak sądzę,
sprzyjasz
1

Prawidłowa odpowiedź na to pytanie brzmi:

  1. To zależy.

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.

tp1
źródło