Odkąd po raz pierwszy dowiedziałem się o wzorach projektowych Gang of Four (GoF) , co najmniej 10 lat temu, mam wrażenie, że te 23 wzory powinny być tylko małą próbką czegoś znacznie większego, co lubię nazywać Przestrzenią Wzorów . Ta hipotetyczna przestrzeń wzorów składa się ze wszystkich godnych polecenia rozwiązań (znanych lub nieznanych) dla typowych problemów projektowych oprogramowania.
Spodziewałem się więc znacznego wzrostu liczby znanych i udokumentowanych wzorców projektowych.
To się nie wydarzyło. Ponad 20 lat po ukazaniu się książki GoF w artykule w Wikipedii wymieniono tylko 12 dodatkowych wzorów, z których większość jest znacznie mniej popularna niż oryginalne. (Nie uwzględniłem tutaj wzorców współbieżności, ponieważ dotyczą one określonego tematu).
Jakie są powody?
Czy zestaw wzorców GoF jest w rzeczywistości bardziej wszechstronny niż myślę?
Czy zainteresowanie znalezieniem nowych wzorców spadło, być może dlatego, że okazały się one mało przydatne w projektowaniu oprogramowania?
Coś innego?
źródło
Odpowiedzi:
Kiedy ukazała się Księga, wiele osób tak myślało i podjęto wiele wysiłków, aby stworzyć „biblioteki wzorców”, a nawet „społeczności wzorców”. Nadal możesz znaleźć niektóre z nich:
Ale wtedy...
To bardzo. Istotą wzorców projektowych jest poprawa komunikacji między programistami, ale jeśli spróbujesz dodać więcej wzorców, szybko dojdziesz do punktu, w którym ludzie nie będą mogli ich zapamiętać, źle je zapamiętać lub nie zgodzić się, jak dokładnie powinni wyglądać, a komunikacja jest w rzeczywistości nie uległa poprawie. To się często zdarza w przypadku wzorców GoF.
Osobiście poszedłbym jeszcze dalej: projektowanie oprogramowania, szczególnie dobre projektowanie oprogramowania, jest zbyt różnorodne, aby można je było w znaczący sposób uchwycić we wzorach, szczególnie w niewielkiej liczbie wzorów, które ludzie mogą zapamiętać - i są one zbyt abstrakcyjne, aby ludzie naprawdę pamiętam więcej niż garść. Więc niewiele pomagają.
Zbyt wiele osób zakochuje się w tej koncepcji i próbuje stosować wzorce wszędzie - zwykle w wynikowym kodzie nie można znaleźć rzeczywistego projektu między wszystkimi (całkowicie bezsensownymi) Singletonami i Fabrykami Abstrakcyjnymi.
źródło
ControversialDesignPatternOnlineOpinionHumanReadableRetortFactory.newInstance().getText();
Jest to przerażające założenie, które propagują wszędzie programiści neofici, programiści, którzy myślą, że mogą napisać program po prostu łącząc wzorce oprogramowania. To nie działa w ten sposób. Jeśli istnieje taka „przestrzeń wzorcowa”, można założyć, że jej rozmiar jest faktycznie nieskończony.
Wzorce projektowe (w sensie GoF) mają tylko jeden cel: zrekompensować braki w używanym języku programowania.
Wzory projektowe nie są uniwersalne ani kompleksowe. Jeśli przejdziesz na inny, bardziej wyrazisty język programowania, większość wzorców w książce GoF stanie się zarówno niepotrzebna, jak i niepożądana.
źródło
ObservableSomething<T>
co ułatwia zrozumienie ich celu, ponieważ używa powszechnie znanej nazwy wzorca. Wzór to pomysł, a nie dokładna implementacja.Myślę, że w grę wchodzą trzy czynniki.
Brak masy krytycznej
Po pierwsze, wzorzec to w zasadzie niewiele więcej niż nadanie nazwy kodowi, który implementuje określony „fragment” funkcjonalności. Jedynym sposobem, w jaki ta nazwa zapewnia prawdziwą wartość, jest to, że możesz polegać na tym, że wszyscy wiedzą, co to znaczy, więc po prostu używając nazwy, od razu rozumieją całkiem sporo o kodzie.
Jednak wzory nigdy nie ustanowiły masy krytycznej, której potrzebowali, aby to osiągnąć. Przeciwnie, AAMOF. W ciągu 20 (lub mniej więcej) lat, odkąd ukazała się książka GoF, jestem prawie pewien, że nie widziałem aż tuzina rozmów, w których wszyscy zaangażowani naprawdę znali wystarczająco dużo wzorców projektowych, aby poprawić komunikację.
Mówiąc nieco bardziej osobliwie: wzorce projektowe zawiodły, ponieważ zawiodły.
Zbyt wiele wzorów
Myślę, że drugim ważnym czynnikiem jest to, że początkowo nazwali zbyt wiele wzorów. W sporej liczbie przypadków różnice między wzorami są na tyle subtelne, że prawie niemożliwe jest stwierdzenie z prawdziwą pewnością, czy dana klasa pasuje do jednego lub drugiego wzoru (a może do obu - a może do żadnego).
Chodziło o to, abyś mógł mówić o kodzie na wyższym poziomie. Dość dużą część kodu można opisać jako implementację określonego wzorca. Po prostu używając tej wstępnie zdefiniowanej nazwy, wszyscy słuchający zwykle wiedzą tyle, ile zależy im na tym kodzie, więc możesz przejść do następnej rzeczy.
Rzeczywistość jest wręcz przeciwna. Powiedzmy, że jesteś na spotkaniu i powiedz im, że ta konkretna klasa to Fasada. Połowa ludzi na spotkaniu albo nigdy nie wiedziała, albo dawno zapomniała dokładnie, co to znaczy. Jeden z nich prosi o przypomnienie mu dokładnej różnicy między fasadą a, powiedzmy, pełnomocnikiem. Aha, a para osób, które naprawdę znają wzorce, spędza resztę spotkania, zastanawiając się, czy to naprawdę powinno być uważane za fasadę, czy „po prostu” adapter (z tym jednym facetem wciąż nalegającym, aby wydawało mu się to pełnomocnikiem).
Biorąc pod uwagę, że naprawdę chciałeś powiedzieć: „ten kod nie jest zbyt interesujący; przejdźmy dalej”, próba użycia nazwy wzorca tylko rozpraszała uwagę, a nie wartość.
Brak zainteresowania
Większość wzorców projektowych tak naprawdę nie zajmuje się interesującymi częściami kodu. Zajmują się takimi sprawami, jak: „jak stworzyć te obiekty?” I „jak sprawić, by ten obiekt z tym rozmawiał?” Zapamiętywanie nazw wzorców dla tych (a także wyżej wymienionych argumentów na temat szczegółów itp.) Po prostu wkłada dużo energii w rzeczy, o których większość programistów po prostu nie dba.
Ujmując to nieco inaczej: wzorce zajmują się tymi samymi rzeczami w wielu programach - ale tak naprawdę program jest interesujący, ponieważ różni się od innych programów.
Podsumowanie
Wzory projektowe zawiodły, ponieważ:
źródło
Wzorcom brakuje abstrakcji, proste wzorce są abstrakcyjne, złożone wzorce nie są rozpoznawane, więc wzorce nie są użyteczne (z wyjątkiem kilku wzorców wysokiego poziomu).
Myślę, że Paul Graham powiedział to najlepiej:
Kiedy rozpoznasz wzorzec w kodzie, oznacza to, że coś się powtarza i powinieneś użyć lepszej abstrakcji. Jeśli nie masz lepszej abstrakcji, zastosujesz wzór jako obejście. Ponieważ nowsze języki programowania zapewniają lepsze abstrakcje, wzorce stają się znacznie mniej przydatne.
Również proste wzory są często łatwe do wyodrębnienia, a złożone wzory rzadko rozpoznawane.
Kiedy wzorzec zastępuje się abstrakcją, nie oznacza to, że koncepcja leżąca u podstaw wzorca znika, ale że pojęcie to można napisać jawnie zamiast pośrednio i że nie jest ono już specjalne w porównaniu z innym kodem i nie jest już rozpoznawalne jako wzorzec.
źródło
String.replace
funkcji, możesz sobie wyobrazić, że wyskakuje ona jako wzorzec, ale lepiej napisać ją raz, niż kontynuować jej implementację. Zgadzam się, że jeśli nie nazwiesz tych rzeczy poprawnie, utrudni to czytanie, ale gdy zrobisz to poprawnie, kod odczyta bardziej deklaratywnie IMO (np.getOrElse
Styl monad opcji vs sprawdzanie wartości zerowej)Chociaż w większości zgadzam się z tym, co odpowiedzieli tu inni, osobiście uważam, że głównym powodem nie rosnącej liczby wzorów jest to, że wzory tracą swoje znaczenie, gdy jest ich niezliczona liczba. Zaletą tych kilku wzorów jest to, że obejmują one wiele domen problemowych w standardowy sposób. Gdybyś skupił się na niekończącej się domenie wzorców, skończyłbyś się bez wzorca. To trochę jak „jak długa jest linia brzegowa wyspy?”. Jeśli mierzysz na mapie, masz przyzwoitą liczbę. Ale jeśli spróbujesz być bardziej dokładny i uzyskasz lepszą rozdzielczość, przekonasz się, że długość rośnie coraz bardziej do nieskończoności (lub niepewności; jak zmierzyłbyś dokładną granicę z pływami i na poziomie atomowym?).
źródło
Coś, o czym żadna z pozostałych odpowiedzi nie wspomina, że jest również istotne:
Wzrost liczby języków pisanych dynamicznie.
Kiedy książka ukazała się po raz pierwszy, istniała poważna dyskusja, że Java jest po prostu zbyt wolna, aby móc naprawdę pracować. Teraz Java jest często używana w bardziej ekspresyjnych językach ze względu na jej szybkość. Być może Ruby, Python, JavaScript i in. Są wciąż zbyt wolne dla niektórych ważnych klas aplikacji, ale ogólnie są wystarczająco szybkie do większości celów. JavaScript przynajmniej przyspiesza, mimo że w każdym wydaniu jest więcej funkcji.
Oryginalna książka GoF miała wzory zarówno w smalltalk, jak i c ++, a jeśli pamięć służy, wzory były zawsze krótsze w smalltalk, a czasem znacznie. Niektóre funkcje klasycznych wzorców projektowych są naprawdę sposobami dodawania dynamicznych funkcji do systemu o typie statycznym (jak już omówiony AbstractFactory, w którym tworzysz poprawną klasę na podstawie danych wykonawczych). Inne są tak dużo krótsze w dynamicznych językach, że po prostu łączą się w idiomatyczne użycie samego języka.
źródło
To się stało. Wydano dziesiątki, jeśli nie setki książek, które wyglądały jak próba zredukowania całej informatyki do wzorców projektowych, gdy wydawcy i autorzy próbowali wskoczyć (lub stworzyć) kolejny nurt. Mam ich półkę. Nigdy nie konsultowałem się od pierwszego zeskanowania, i tak, byłem frajerem, ponieważ było niewiele lub nic tam nie było żadnego rzeczywistego zastosowania lub nie było to jeszcze dobrze znane (patrz na przykład Obiekt Obiekt, który jest niczym więcej niż trzecią normalną formą wyrażoną ponad kilkanaście stron zamiast jednego akapitu), a ponieważ oczywiście im mniej wzorów, tym lepiej: kwestia, która wymknęła się większości praktykujących. Rzeczywiście, kiedy zamieściłem obalenie Type Type, polecono mi przekształcić tekst jako wzorzec projektowy.Prawdziwa historia. Co pokazuje także inną wadę projektu: brak mechanizmu przeglądu, wykluczenia lub odrzucenia.
W rzeczywistości GoF nie próbował „dokładnie zbadać Wzorów Projektowych”. Zamiast tego zaangażowali się w znacznie większy projekt: wprowadzenie „języka wzorcowego” do CS, ze wszystkimi jego dziwnymi arkanicznymi notacjami Sił, Uczestników itp., Które po prostu zawiodły, ponieważ były zasadniczo błędnie rozumiane, a także były bezcelowe.
Co oni nie osiągnąć, co było przydatne, to dwie rzeczy:
Inną przydatną koncepcją, która się pojawiła, był „anty-wzór”, np. „Loguj i rzucaj”. Projekt, podobnie jak wiele modnych w CS, został wykolejeni przez własną ewangelizację i przez pomyłkę przyjęty jako kolejna religia CS, i poszedł w ślady większości takich religii: użyteczne w częściach, ale z pewnością „bez srebrnej kuli” ((c ) Fred Brooks, 1965). Smutne, że musimy odkrywać to na nowo co kilka lat.
źródło
Było / jest kilka książek zatytułowanych PLoP ( Pattern Languages of Program Design ), z których każda jest antologią artykułów prezentowanych na dorocznej konferencji .
Czytając książki, odkryłem, że niektóre wzory były dla mnie interesujące i nowe, niektóre ze standardów (np. „Pół obiekt plus protokół”).
Więc nie, kolekcja GoF nie była wyczerpująca i zainspirowała / zainspirowała ludzi do zbierania / opisywania / odkrywania / wymyślania nowych.
„Tylko 12 dodatkowych wzorów wymienionych w artykule w Wikipedii” prawdopodobnie nie jest również kompletnym zbiorem: tzn. Istnieją inne udokumentowane gdzie indziej, np. W książkach PLoP, a może także gdzie indziej.
źródło
Książka Gang of Four (GoF) zawiera większość wzorów, które doświadczony programista w niefunkcjonalnym języku ma w swoim pasku narzędzi. To jest jak podstawowy zestaw narzędzi, z których wszyscy budowniczowie wiedzą, jak korzystać. Podstawowym wkładem książki było nadanie dobrze zdefiniowanej nazwy wzorcom, które były powszechnie używane w tym czasie przez najbardziej doświadczonych programistów, a tym samym pomoc w komunikacji między programistami omawiającymi opcje projektowania.
Oczekujesz, że elektryk będzie miał narzędzia, których nie ma normalny konstruktor, podobnie możesz oczekiwać od programisty WPF, który zna wzorce projektowe dla „Właściwości zależności”, lub „programisty SQL”, który zna wzorzec projektowy do używania wyzwalaczy do tworzyć dane audytu.
Nie uważamy ich jednak za „wzorce projektowe”, ponieważ są one używane tylko z jedną technologią.
Kolejne wzorce projektowania modemu to: „Refaktoryzacja, ulepszanie projektowania istniejącego kodu (Martin Fowler)” i „Clean Code: Handbook of Agile Software Craftsmanship (Robert C. Martin) ”. Obie te książki przedstawiają treść jako dokonane transformacje do obecnego kodu, a nie jako „projekt wielokrotnego użytku w puszkach”, jednak są one w równym stopniu „wzorami projektowymi”.
źródło
Oto wywiad z Erichem Gammą, w którym zastanawia się nad ich wyborem wzorców i tym, co zmieniliby dzisiaj (dobrze dzisiaj 10 lat temu, haha).
http://www.informit.com/articles/article.aspx?p=1404056
źródło
Rzeczywiste wzorce w książce są czasami bardzo przydatne, ale w rzeczywistości są to po prostu przykłady potężniejszego narzędzia, które daje ci książka: głębokie zrozumienie, kiedy i gdzie lepiej wyciąć kod monolityczny w niezależnych częściach oddzielonych i regulowanych przez interfejs .
Kiedy uczysz się tej umiejętności, zdajesz sobie sprawę, że nie musisz pamiętać dokładnych szczegółów każdego pojedynczego wzoru, ponieważ zawsze możesz wyciąć wdrażane rozwiązanie w sposób, który najlepiej pasuje do jego celu. Pomysł zapisywania coraz większej liczby wzorów wydaje się bardzo akademicki i bezcelowy.
źródło
Książka GoF i Wikipedia nie są jedynym źródłem znanych wzorców projektowych. Jeśli po prostu wyszukujesz „wzorce projektowe” w Amazon.com, otrzymujesz setki książek (spróbuj tego wyszukiwania ). Sądzę, że podają tylko najbardziej znany wzorzec w artykule na Wikipedii .
Problemem nie jest to, że nie ma wystarczającej liczby udokumentowanych wzorców projektowych. Raczej jest ich tak wiele, że nikt nie może zapamiętać ich wszystkich, a większość programistów rozpoznaje tylko kilka. W tym momencie załamuje się duża obietnica wspólnego języka wzorców.
źródło
Prawdopodobnie istnieje wiele konstrukcji, o których jeszcze nie pomyślano. Tak długo, jak ludzie opracowują oprogramowanie, pojawią się wyzwania projektowe do pokonania. Niektóre z nich mogą być rozwiązane za pomocą sprytnych nowych wzorów, z których inni mogliby skorzystać.
Języki programowania rozwinęły się i posunęły do wyodrębnienia najczęściej używanych wzorców. Wzory te nadal istnieją w projektowaniu języków. Dlatego mogą być dzisiaj zignorowani, ale to nie czyni ich nieważnymi.
Czy wiedza o tym, jak zbudować dom, nagle przestaje mieć znaczenie, gdy mamy roboty, które mogą to dla nas zrobić? Twierdziłbym, że nie, nie jest. Jest to mniej istotne, pewne - i prawdopodobnie o wiele mniej satysfakcjonujące w nauce, ponieważ popyt gwałtownie spadł i nikt inny go nie studiuje.
Więc nie, nie wierzę, że przestrzeń wzorów, jak ją nazywacie, została wyczerpana. Jak wskazała inna odpowiedź, prawdopodobnie będzie nieskończona. Ale wraz ze spadkiem zapotrzebowania na projektowanie systemów, wraz ze wzrostem wysokości naszej wieży abstrakcji i mocy naszych języków programowania - coraz mniej osób budujących na najwyższych kondygnacjach zwróci uwagę na szczegóły budowy wieży .
źródło
Wzorce są nieskończone .. Możesz dostosować każdy wzorzec lub mieszać n dopasować, aby utworzyć nowe. Wzorce integracji korporacyjnej są również dobrze zdefiniowane .. więc tak, gof wziął problem z dokumentowaniem wzorców za pomocą uml i stworzył standard ich wyjaśniania .. Ale dla każdej domeny ewoluują wzorce i zmieniają się one także dla ekspresyjnego języka, takiego jak python lub scala ..
źródło