Odkąd zacząłem uczyć się F # i OCaml w zeszłym roku, przeczytałem ogromną liczbę artykułów, które twierdzą, że wzorce projektowe (szczególnie w Javie) są obejściem brakujących funkcji w imperatywnych językach. Jeden artykuł, który znalazłem, zawiera dość silne twierdzenie :
Większość ludzi, których spotkałem, przeczytała książkę Design Patterns autorstwa Gang of Four (GoF). Każdy szanujący się programista powie ci, że książka jest niezależna od języka, a wzorce dotyczą ogólnie inżynierii oprogramowania, niezależnie od tego, jakiego języka używasz. To szlachetne roszczenie. Niestety jest to dalekie od prawdy.
Języki funkcjonalne są niezwykle ekspresyjne. W języku funkcjonalnym nie trzeba wzorców projektowych, ponieważ język jest prawdopodobnie tak wysoki, że kończy się programowanie w koncepcjach, które całkowicie eliminują wzorce projektowe.
Główne cechy programowania funkcjonalnego (FP) obejmują funkcje jako wartości pierwszej klasy, curry, wartości niezmienne itp. Nie wydaje mi się oczywiste, że wzorce projektowe OO zbliżają którąkolwiek z tych cech.
Dodatkowo w językach funkcjonalnych, które obsługują OOP (takich jak F # i OCaml), wydaje mi się oczywiste, że programiści używający tych języków używają tych samych wzorców projektowych, które są dostępne dla każdego innego języka OOP. W rzeczywistości teraz używam F # i OCaml każdego dnia i nie ma uderzających różnic między wzorami używanymi w tych językach a wzorami używanymi podczas pisania w Javie.
Czy istnieje jakaś prawda w twierdzeniu, że programowanie funkcjonalne eliminuje potrzebę wzorców projektowych OOP? Jeśli tak, to czy możesz zamieścić przykładowy typowy wzorzec projektowy OOP i jego funkcjonalny odpowiednik?
Odpowiedzi:
Cytowany post na blogu jest nieco zawyżony. FP nie eliminuje potrzeby tworzenia wzorów. Termin „wzorce projektowe” po prostu nie jest powszechnie używany do opisania tego samego w językach FP. Ale istnieją. Języki funkcjonalne mają wiele zasad najlepszych praktyk w formie „gdy napotkasz problem X, użyj kodu, który wygląda jak Y”, co jest w zasadzie wzorcem projektowym.
Prawdą jest jednak, że większość wzorców projektowych specyficznych dla OOP jest praktycznie nieistotna w językach funkcjonalnych.
Nie sądzę, że powinno to być szczególnie kontrowersyjna powiedzieć, że wzorce projektowe w ogóle istnieć tylko załatać braki w języku. A jeśli inny język może rozwiązać ten sam problem w sposób trywialny, ten inny język nie będzie potrzebował wzorca projektowego. Użytkownicy tego języka mogą nawet nie zdawać sobie sprawy, że problem istnieje , ponieważ cóż, w tym języku nie jest to problem.
Oto, co Gang of Four ma do powiedzenia na ten temat:
(Powyższy cytat z książki Wprowadzenie do wzorców projektowych, strona 4, akapit 3)
Jaki jest wzorzec poleceń, jeśli nie przybliżenie funkcji pierwszej klasy? :) W języku FP wystarczy przekazać funkcję jako argument do innej funkcji. W języku OOP musisz zawinąć funkcję w klasę, którą możesz utworzyć, a następnie przekazać ten obiekt do innej funkcji. Efekt jest taki sam, ale w OOP nazywa się to wzorcem projektowym i zajmuje o wiele więcej kodu. A jaki jest abstrakcyjny wzór fabryki, jeśli nie curry? Przekaż parametry do funkcji po trochu, aby skonfigurować, jaka wartość będzie wyrzucana, gdy w końcu ją wywołasz.
Tak więc, kilka wzorców projektowych GoF jest nadmiarowych w językach FP, ponieważ istnieją bardziej wydajne i łatwiejsze w użyciu alternatywy.
Ale oczywiście nadal istnieją wzorce projektowe, których nie rozwiązują języki FP. Jaka jest równowartość FP singletona? (Pomijając przez chwilę to, że singletony są na ogół okropnym wzorem do użycia.)
I działa to w obie strony. Jak powiedziałem, FP ma również swoje wzorce projektowe; ludzie zwykle nie myślą o nich jako o takich.
Być może natknąłeś się na monady. Co to jest, jeśli nie wzór do „radzenia sobie ze stanem globalnym”? Jest to problem tak prosty w językach OOP, że nie istnieje tam równoważny wzorzec projektowy.
Nie potrzebujemy wzorca projektowego do „zwiększania zmiennej statycznej” lub „odczytu z tego gniazda”, ponieważ jest to tylko to, co robisz .
Mówienie, że monada jest wzorcem projektowym, jest równie absurdalne, jak twierdzenie, że liczby całkowite z ich zwykłymi operacjami, a element zerowy jest wzorcem projektowym. Nie, monada to wzór matematyczny , a nie wzór projektowy.
W (czystych) językach funkcjonalnych efekty uboczne i stan mutable są niemożliwe, chyba że obejdziesz je z monadowym „wzorcem projektowym” lub innymi metodami pozwalającymi na to samo.
Może dlatego, że nadal myślisz imperatywnie? Wiele osób, które przez całe życie miały do czynienia z imperatywnymi językami, z trudem rezygnuje z tego nawyku, próbując języka funkcjonalnego. (Widziałem kilka dość zabawnych prób na F #, gdzie dosłownie każda funkcja była tylko ciągiem instrukcji „let”, zasadniczo tak, jakbyś wziął program C i zastąpił wszystkie średniki słowem „let”. :))
Ale inną możliwością może być to, że po prostu nie zdajesz sobie sprawy, że rozwiązujesz problemy w sposób trywialny, które wymagałyby wzorców projektowych w języku OOP.
Kiedy używasz curry lub przekazujesz funkcję jako argument innemu, zatrzymaj się i pomyśl o tym, jak zrobiłbyś to w języku OOP.
Tak. :) Kiedy pracujesz w języku FP, nie potrzebujesz już wzorów projektowania specyficznych dla OOP. Nadal jednak potrzebujesz ogólnych wzorców projektowych, takich jak MVC lub inne rzeczy niezwiązane z OOP, a zamiast tego potrzebujesz kilku nowych „wzorców projektowych” specyficznych dla FP. Wszystkie języki mają swoje wady, a wzorce projektowe są zwykle takie, jak je omawiamy.
W każdym razie może być interesujące wypróbowanie swoich „czystszych” języków FP, takich jak ML (mój osobisty ulubiony, przynajmniej do celów edukacyjnych) lub Haskell , gdzie nie masz kuli OOP, na której można polegać , gdy napotyka coś nowego.
Zgodnie z oczekiwaniami kilka osób sprzeciwiło się mojej definicji wzorców projektowych jako „łatanie niedociągnięć w języku”, więc oto moje uzasadnienie:
Jak już powiedziano, większość wzorców projektowych jest charakterystyczna dla jednego paradygmatu programowania, a czasem nawet jednego określonego języka. Często rozwiązują problemy, które istnieją tylko w tym paradygmacie (patrz monady dla FP lub abstrakcyjne fabryki dla OOP).
Dlaczego abstrakcyjny wzór fabryczny nie istnieje w FP? Ponieważ problem, który próbuje rozwiązać, nie istnieje.
Tak więc, jeśli istnieje problem w językach OOP, który nie występuje w językach FP, to oczywiście jest to wada języków OOP. Problem można rozwiązać, ale twój język tego nie robi, ale wymaga od ciebie garstki kodu do obejścia. Idealnie byłoby, gdyby nasz język programowania w magiczny sposób rozwiązał wszystkie problemy. Jakikolwiek problem, który nadal występuje, jest w zasadzie wadą języka. ;)
źródło
Programowanie funkcjonalne to nie to samo, co programowanie obiektowe. Obiektowe wzorce projektowe nie dotyczą programowania funkcjonalnego. Zamiast tego masz funkcjonalne wzorce projektowe programowania.
Do programowania funkcjonalnego nie będziesz czytać wzorców projektowych OO; przeczytasz inne książki o wzorach projektowych FP.
Nie całkiem. Jedynie niezależny od języka w odniesieniu do języków OO. Wzory projektowe w ogóle nie dotyczą języków proceduralnych. Nie mają one sensu w kontekście projektowania relacyjnych baz danych. Nie mają zastosowania przy projektowaniu arkusza kalkulacyjnego.
Powyższe nie powinno istnieć. To tak, jakby poprosić o kawałek kodu proceduralnego przepisanego jako kod OO. Ummm ... Jeśli przetłumaczę oryginalny Fortran (lub C) na Javę, nie zrobiłem nic poza tłumaczeniem. Jeśli całkowicie przepisam go na paradygmat OO, nie będzie już wyglądał jak oryginalny Fortran lub C - będzie nierozpoznawalny.
Nie ma prostego mapowania od projektu OO do projektu funkcjonalnego. Są bardzo różne sposoby patrzenia na problem.
Programowanie funkcjonalne (jak wszystkie style programowania) ma wzorce projektowe. Relacyjne bazy danych mają wzorce projektowe, OO ma wzorce projektowe, a programowanie proceduralne ma wzorce projektowe. Wszystko ma wzory, nawet architekturę budynków.
Wzory projektowe - jako koncepcja - to ponadczasowy sposób budowania, niezależnie od technologii czy dziedziny problemowej. Jednak określone wzorce projektowe dotyczą określonych domen i technologii problemowych.
Każdy, kto myśli o tym, co robi, odkryje wzorce projektowe.
źródło
Komentarze Briana na temat ścisłego powiązania języka z wzorcem są takie, że
Brakującą częścią tej dyskusji jest koncepcja idiomu. Ogromny wpływ miała tu książka Jamesa O. Coplien'a „Advanced C ++”. Na długo przed odkryciem Christophera Alexandra i kolumny bez imienia (i nie można też rozsądnie mówić o wzorach bez czytania Aleksandra), mówił o znaczeniu opanowania idiomów w prawdziwej nauce języka. Jako przykład posłużył się tekstem w C,
while(*from++ = *to++);
możesz to zobaczyć jako bandaid dla brakującego języka (lub biblioteki), ale tak naprawdę liczy się to, że jest to większa jednostka myśli lub wyrażenia niż jakakolwiek jego części.Właśnie takie wzorce i języki starają się zrobić, abyśmy mogli bardziej zwięźle wyrazić nasze intencje. Im bogatsze jednostki myśli, tym bardziej złożone myśli możesz wyrazić. Posiadanie bogatego, wspólnego słownictwa w różnych skalach - od architektury systemu po kręcenie się - pozwala nam na bardziej inteligentne rozmowy i przemyślenia na temat tego, co powinniśmy robić.
Możemy również, jako jednostki, uczyć się. Co jest celem całego ćwiczenia. Każdy z nas może zrozumieć i korzystać z rzeczy, o których nigdy nie moglibyśmy myśleć o sobie. Języki, frameworki, biblioteki, wzorce, idiomy itd. Mają swoje miejsce w dzieleniu się bogactwem intelektualnym.
źródło
Książka GoF wyraźnie wiąże się z OOP - tytuł to Design Patterns - Elements of Wielorazowe oprogramowanie obiektowe (moje wyróżnienie ).
źródło
Wzory projektowe w programowaniu dynamicznym autorstwa Petera Norviga w przemyślany sposób omawiają ten ogólny temat, choć o językach „dynamicznych” zamiast „funkcjonalnych” (nakładają się na siebie).
źródło
Oto kolejny link omawiający ten temat: http://blog.ezyang.com/2010/05/design-patterns-in-haskel/
W swoim blogu Edward opisuje wszystkie 23 oryginalne wzorce GoF w kategoriach Haskell.
źródło
Kiedy spróbujesz spojrzeć na to na poziomie „wzorców projektowych” (ogólnie) i „FP kontra OOP”, odpowiedzi, które znajdziesz, będą co najwyżej mroczne.
Przejdź jednak poziom głębiej na obu osiach i zastanów się nad konkretnymi wzorami projektowymi i specyficznymi cechami językowymi, a rzeczy staną się wyraźniejsze.
Na przykład niektóre określone wzorce, takie jak Odwiedzający , Strategia , Polecenie i Obserwator zdecydowanie zmieniają się lub znikają podczas używania języka z algebraicznymi typami danych i dopasowaniem wzorców , zamknięciami , funkcjami pierwszej klasy itp. Niektóre inne wzorce z książki GoF wciąż „trzymać się”.
Ogólnie rzecz biorąc, powiedziałbym, że z czasem określone wzorce są eliminowane przez nowe (lub po prostu rosnące w popularności) funkcje językowe. To naturalny kurs projektowania języka; gdy języki stają się coraz bardziej zaawansowane, abstrakcje, które wcześniej można było wywołać tylko w książce na przykładach, teraz stają się aplikacjami określonej funkcji językowej lub biblioteki.
(Na bok: oto niedawno napisany blog , który zawiera inne linki do dalszych dyskusji na temat FP i wzorców projektowych.)
źródło
for
pętli, a wszystkie mają po prostuwhile
pętle, wówczas „For” może być wzorem iteracji. Ale kiedyfor
jest to konstrukcja obsługiwana przez język i sposób, w jaki ludzie normalnie kodują, to nie jest to wzorzec - nie nie potrzebuje wzorca, to tylko kod, człowieku.)foreach
a HaskellmapM
nie oznacza, że nie mają wzorca iteratora. Nie widzę problemu z powiedzeniem, że wzorzec Iteratora jest zaimplementowany jako ogólny interfejsIEnumerable<T>
w C # i krój pismaTraversable
w Haskell.Prezentacja Norviga nawiązuje do dokonanej przez nich analizy wszystkich wzorców GoF i mówią, że 16 z 23 wzorców miało prostsze implementacje w językach funkcjonalnych lub po prostu było częścią tego języka. Prawdopodobnie co najmniej siedem z nich było a) równie skomplikowanych lub b) nieobecnych w języku. Niestety dla nas nie są one wymienione!
Myślę, że jest jasne, że większość wzorców „kreacyjnych” lub „strukturalnych” w GoF to tylko sztuczki, aby zmusić prymitywne systemy typów w Javie lub C ++ do robienia tego, co chcesz. Ale reszta jest warta rozważenia bez względu na język, w którym programujesz.
Jednym może być Prototyp; Chociaż jest to podstawowe pojęcie JavaScript, musi być zaimplementowane od podstaw w innych językach.
Jednym z moich ulubionych wzorów jest wzorzec Null Object: reprezentuje brak czegoś jako obiektu, który nie robi odpowiedniego rodzaju niczego. To może być łatwiejsze do modelowania w funkcjonalnym języku. Jednak prawdziwym osiągnięciem jest zmiana perspektywy.
źródło
Powiedziałbym, że jeśli masz język taki jak Lisp z obsługą makr, możesz zbudować własne abstrakcje specyficzne dla domeny, abstrakcje, które często są znacznie lepsze niż ogólne rozwiązania idiomowe.
źródło
I nawet rozwiązania wzorców projektowych OO są specyficzne dla języka.
Wzorce projektowe są rozwiązaniem typowych problemów, których Twój język programowania nie rozwiązuje dla Ciebie. W Javie wzorzec Singleton rozwiązuje problem jednego (uproszczonego).
W Scali masz konstrukcję najwyższego poziomu o nazwie Object oprócz Class. Jest on leniwie utworzony i jest tylko jeden. Nie musisz używać wzoru Singleton, aby otrzymać Singleton. To część języka.
źródło
Wzorce są sposobami rozwiązywania podobnych problemów, które pojawiają się wielokrotnie, a następnie są opisywane i dokumentowane. Więc nie, FP nie zastąpi wzorów; FP mogą jednak tworzyć nowe wzorce i sprawić, że niektóre obecne wzorce „najlepszych praktyk” staną się „przestarzałe”.
źródło
Jak powiedzieli inni, istnieją wzorce specyficzne dla programowania funkcjonalnego. Myślę, że kwestia pozbycia się wzorców projektowych to nie tyle kwestia przejścia na funkcjonalność, co kwestia cech językowych .
Spójrz, jak Scala eliminuje „wzorzec singletonu”: po prostu deklarujesz obiekt zamiast klasy. Kolejna funkcja, dopasowywanie wzorów, pomaga uniknąć niezręczności wzoru odwiedzającego. Zobacz porównanie tutaj: Scala's Pattern Matching = wzór gościa na sterydach
A Scala, podobnie jak F #, jest połączeniem funkcji OO. Nie wiem o F #, ale prawdopodobnie ma tego rodzaju funkcje.
Zamknięcia są obecne w języku funkcjonalnym, ale nie muszą być do nich ograniczone. Pomagają we wzorcu delegowania.
Jeszcze jedna obserwacja. Ten fragment kodu implementuje wzorzec: jest tak klasyczny i tak elementarny, że zwykle nie uważamy go za „wzorzec”, ale z pewnością jest to:
Języki imperatywne, takie jak Java i C #, przyjęły coś, co jest zasadniczo funkcjonalnym konstruktem, aby sobie z tym poradzić: „foreach”.
źródło
Wzory projektowe GoF kodują obejścia przepisów dla języków OO, które są potomkami Simula 67 , takich jak Java i C ++.
Większość „dolegliwości” leczonych przez wzorce projektowe jest spowodowana:
Nie ma jednego z tych wzorców projektowych, który nie zniknie we wspólnym systemie obiektowym Lisp, nawet jeśli rozwiązanie jest zbudowane zasadniczo w taki sam sposób, jak w odpowiednim wzorcu projektowym. (Co więcej, ten system obiektowy poprzedza książkę GoF znacznie ponad dekadę. Common Lisp stał się standardem ANSI w tym samym roku, w którym po raz pierwszy opublikowano tę książkę.)
Jeśli chodzi o programowanie funkcjonalne, to czy wzorce mają do niego zastosowanie, zależy od tego, czy dany funkcjonalny język programowania ma jakiś system obiektowy i czy jest modelowany na podstawie systemów obiektowych, które korzystają z wzorców. Tego rodzaju orientacja obiektowa nie łączy się dobrze z programowaniem funkcjonalnym, ponieważ mutacja stanu znajduje się z przodu i na środku.
Konstrukcja i niezmutowany dostęp są kompatybilne z programowaniem funkcjonalnym, więc mogą mieć zastosowanie wzorce, które mają związek z dostępem abstrakcyjnym lub konstrukcją: wzorce takie jak Fabryka, Fasada, Serwer proxy, Dekorator i Gość.
Z drugiej strony wzorce behawioralne, takie jak stan i strategia, prawdopodobnie nie mają bezpośredniego zastosowania w funkcjonalnym OOP, ponieważ mutacja stanu leży u ich podstaw. To nie znaczy, że nie mają zastosowania; być może w jakiś sposób mają zastosowanie w połączeniu z wszelkimi dostępnymi sztuczkami do symulacji stanu zmiennego.
źródło
Chciałbym podłączyć kilka doskonałych, ale nieco gęstych dokumentów Jeremy'ego Gibbonsa: „Projektuj wzorce jako programy generyczne dla typów danych wyższego rzędu” i „Istota wzorca Iterator” (oba dostępne tutaj: http: // www. comlab.ox.ac.uk/jeremy.gibbons/publications/ ).
Oba opisują, w jaki sposób idiomatyczne konstrukcje funkcjonalne pokrywają teren objęty określonymi wzorami projektowymi w innych (obiektowych) ustawieniach.
źródło
Nie można prowadzić tej dyskusji bez wywoływania systemów typów.
To dlatego, że te funkcje nie dotyczą tych samych problemów, co OOP ... są alternatywą dla programowania imperatywnego. Odpowiedź FP na OOP leży w systemach typów ML i Haskell ... w szczególności typów sum, abstrakcyjnych typów danych, modułów ML i klas Haskell.
Pierwszą rzeczą, jaką robią typy, jest wyeliminowanie potrzeby singletonów.
Możesz przejrzeć listę 23 i wyeliminować więcej, ale nie mam teraz na to czasu.
źródło
Myślę, że tylko dwa wzorce projektowe GoF zostały zaprojektowane w celu wprowadzenia logiki programowania funkcjonalnego do naturalnego języka OO. Myślę o strategii i dowodzeniu. Niektóre inne wzorce projektowe GoF można modyfikować za pomocą programowania funkcjonalnego, aby uprościć projekt i zachować cel.
źródło
Zasadniczo tak !
Poza tym ta strona (AreDesignPatternsMissingLanguageFeatures) zawiera tabelę tłumaczeń „wzorzec / cecha” oraz kilka ciekawych dyskusji, jeśli chcesz kopać.
źródło
Programowanie funkcjonalne nie zastępuje wzorców projektowych. Wzorów projektowych nie można zastąpić.
Wzory po prostu istnieją; pojawiły się z czasem. Książka GoF sformalizowała niektóre z nich. Jeśli pojawią się nowe wzorce, gdy programiści używają funkcjonalnych języków programowania, to jest ekscytujące rzeczy i być może zostaną też napisane o nich książki.
źródło
W nowej książce z 2013 roku zatytułowanej „Functional Programming Patterns- in Scala and Clojure” autor Michael.B. Linn wykonuje przyzwoitą pracę, porównując i zastępując w wielu przypadkach wzorce GoF, a także omawia nowsze wzorce funkcjonalne, takie jak „rekurencja ogona”, „zapamiętywanie”, „leniwa sekwencja” itp.
Ta książka jest dostępna na Amazon. Uznałem, że jest to bardzo pouczające i zachęcające, gdy pochodzę z kilkudziesięcioletniego doświadczenia w OO.
źródło
Wzorce OOP i GoF dotyczą stanów. OOP modeluje rzeczywistość, aby baza kodu była jak najbardziej zbliżona do podanych wymagań rzeczywistości. Wzorce projektowe GoF to wzorce zidentyfikowane w celu rozwiązania problemów rzeczywistych atomów. Podchodzą do problemu państwa w sposób semantyczny.
Ponieważ w rzeczywistym programowaniu funkcjonalnym nie istnieje żaden stan, nie ma sensu stosowanie wzorców GoF. Nie istnieją funkcjonalne wzorce projektowe w taki sam sposób, jak wzorce projektowe GoF. Każdy wzór funkcjonalny jest sztuczny w przeciwieństwie do rzeczywistości, ponieważ funkcje są konstrukcjami matematyki, a nie rzeczywistości.
Funkcje nie mają pojęcia czasu, ponieważ zawsze zwracają tę samą wartość bez względu na aktualny czas, chyba że czas jest częścią parametrów funkcji, co naprawdę utrudnia przetwarzanie „przyszłych żądań”. Języki hybrydowe mieszają te koncepcje, dzięki czemu języki te nie są prawdziwymi funkcjonalnymi językami programowania.
Języki funkcjonalne rosną tylko z jednego powodu: obecnych naturalnych ograniczeń fizyki. Dzisiejsze procesory mają ograniczoną szybkość przetwarzania instrukcji ze względu na prawa fizyczne. Widoczna jest stagnacja częstotliwości zegara, ale rozszerzenie rdzeni przetwarzających. Dlatego równoległość instrukcji staje się coraz ważniejsza, aby zwiększyć szybkość nowoczesnych aplikacji. Ponieważ programowanie funkcjonalne z definicji nie ma stanu i dlatego nie ma skutków ubocznych, bezpieczne jest równoległe przetwarzanie funkcji.
Wzorce GoF nie są przestarzałe. Są one co najmniej niezbędne do modelowania rzeczywistych wymagań. Ale jeśli używasz funkcjonalnego języka programowania, musisz przekształcić je w ich hybrydowe odpowiedniki. Wreszcie nie masz szansy tworzyć programów funkcjonalnych, jeśli używasz wytrwałości. W przypadku elementów hybrydowych Twojego programu konieczne jest stosowanie wzorców GoF. Dla każdego innego elementu, który jest czysto funkcjonalny, nie ma potrzeby używania wzorców GoF, ponieważ nie ma stanu.
Ponieważ wzorce GoF nie są konieczne do prawdziwego programowania funkcjonalnego, nie oznacza to, że nie należy stosować zasad SOLID. Zasady SOLID wykraczają poza paradygmat języka.
źródło
W programowaniu funkcjonalnym wzorce projektowe mają inne znaczenie. W rzeczywistości większość wzorców projektowych OOP jest niepotrzebna w programowaniu funkcjonalnym ze względu na wyższy poziom abstrakcji i wartości HOF wykorzystywane jako elementy składowe.
źródło
Zgodnie z przyjętą odpowiedzią, OOP i FP mają swoje specyficzne wzorce.
Istnieją jednak pewne wzorce, które są tak powszechne, że powinny istnieć wszystkie platformy programistyczne, o których myślę. Oto (niekompletna) lista:
Adapter. Nie mogę sobie wyobrazić użytecznej platformy programistycznej, która jest tak kompleksowa (i samospełniająca się), że nie musi rozmawiać ze światem. Jeśli ma to zrobić, zdecydowanie potrzebny jest adapter.
Fasada. Wszelkie platformy programistyczne, które mogą obsługiwać duży kod źródłowy, powinny mieć możliwość modularyzacji. Jeśli chcesz utworzyć moduł dla innych części programu, będziesz chciał ukryć „brudne” części kodu i nadać mu ładny interfejs.
Interpretator. Ogólnie rzecz biorąc, każdy program wykonuje dwie czynności: analizuje dane wejściowe i dane wyjściowe wydruku. Dane wejściowe myszy muszą zostać przeanalizowane, a widżety okien wydrukowane. Dlatego posiadanie wbudowanego interpretera daje programowi dodatkową moc dostosowywania.
Zauważyłem też, że w typowym języku FP, Haskell, istnieje coś podobnego do wzorców GoF, ale o różnych nazwach. Moim zdaniem sugeruje to, że oni tam byli, ponieważ istnieją pewne typowe problemy do rozwiązania zarówno w językach FP, jak i OOP.
źródło
Myślę, że każdy paradygmat służy innemu celowi i jako taki nie może być porównywany w ten sposób.
Nie słyszałem, że wzorce projektowe GoF mają zastosowanie do każdego języka. Słyszałem, że mają zastosowanie do wszystkich języków OOP . Jeśli używasz programowania funkcjonalnego, dziedzina problemów, które rozwiązujesz, jest inna niż języki OO.
Nie użyłbym języka funkcjonalnego do napisania interfejsu użytkownika, ale jeden z języków OO, takich jak C # lub Java, ułatwiłby to zadanie. Gdybym pisał funkcjonalny język, nie rozważałbym używania wzorców projektowych OO.
źródło
OOP i FP mają różne cele. OOP ma na celu hermetyzację złożoności / ruchomych części komponentów oprogramowania, a FP ma na celu zminimalizowanie złożoności i zależności komponentów oprogramowania.
Jednak te dwa paradygmaty niekoniecznie są w 100% sprzeczne i można je zastosować razem, aby uzyskać korzyści z obu światów.
Nawet w języku, który nie obsługuje natywnie programowania funkcjonalnego, takiego jak C #, możesz napisać kod funkcjonalny, jeśli rozumiesz zasady FP. Podobnie możesz zastosować zasady OOP za pomocą F #, jeśli rozumiesz zasady, wzorce i najlepsze praktyki OOP. Dokonałbyś właściwego wyboru na podstawie sytuacji i problemu, który próbujesz rozwiązać, niezależnie od używanego języka programowania.
źródło
Niektóre wzorce są łatwiejsze do wdrożenia w języku wspierającym FP. Na przykład strategię można wdrożyć, ładnie wykorzystując zamknięcia. Jednak w zależności od kontekstu możesz preferować implementację strategii przy użyciu podejścia klasowego, powiedzmy tam, gdzie same strategie są dość skomplikowane i / lub udostępniaj strukturę, którą chcesz modelować przy użyciu metody szablonu.
Z mojego doświadczenia rozwijającego się w języku z wieloma paradygmatami (Ruby), implementacja FP działa dobrze w prostych przypadkach, ale tam, gdzie kontekst jest bardziej skomplikowany, podejście oparte na OF GoF jest lepsze.
Podejście FP nie zastępuje podejścia OOP, ale je uzupełnia.
źródło
Najważniejszą cechą programowania funkcjonalnego, IMHO, jest to, że programujesz tylko za pomocą wyrażeń - wyrażeń w wyrażeniach w wyrażeniach, które wszystkie oceniają do ostatniego, końcowego wyrażenia, które „ogrzewa maszynę podczas oceny”.
Najważniejszą cechą programowania obiektowego, IMHO jest to, że programujesz z obiektami o stanie wewnętrznym. Nie można mieć stanu wewnętrznego w czystych funkcjach - obiektowe języki programowania potrzebują instrukcji, aby coś się stało. (W programowaniu funkcjonalnym nie ma instrukcji).
Porównujesz jabłka do pomarańczy. Wzorce programowania obiektowego nie mają zastosowania do programowania funkcji, ponieważ programowanie funkcjonalne to programowanie wyrażeniami, a programowanie obiektowe to programowanie ze stanem wewnętrznym.
źródło
Przygotuj się.
Zirytuje to wielu, słysząc, jak twierdzę, że zastąpiłem wzorce projektowe i obaliłem SOLID i SUCHO. Jestem nikim. Niemniej jednak poprawnie modelowałem architekturę współpracy (produkcji) i opublikowałem zasady budowania procesów online wraz z kodem i nauką stojącą za tym na mojej stronie internetowej http://www.powersemantics.com/ .
Moim argumentem jest to, że wzorce projektowe starają się osiągnąć to, co produkcja nazywa „masową personalizacją”, formą procesu, w której każdy krok może zostać przekształcony, ponownie skomponowany i rozszerzony. Możesz myśleć o takich procesach jak nieskompilowanych skryptach. Nie zamierzam tutaj powtarzać mojego (internetowego) argumentu. Krótko mówiąc, moja architektura masowego dostosowywania zastępuje wzorce projektowe, osiągając tę elastyczność bez zbędnej semantyki. Byłem zaskoczony, że mój model działał tak dobrze, ale sposób, w jaki programiści piszą kod, po prostu nie znosi tego, jak produkcja organizuje współpracę.
Ta architektura nigdy nie wymaga refaktoryzacji. Istnieją również zasady dotyczące centralizacji i dystrybucji, które wpływają na złożoność. Ale aby odpowiedzieć na twoje pytanie, programowanie funkcjonalne jest kolejnym zestawem semantyki przetwarzania, a nie architekturą dla masowych procesów niestandardowych, w których 1) routing źródłowy istnieje jako (skryptowy) dokument, który właściciel może przepisać przed odpaleniem, a 2) moduły mogą być łatwo i dynamicznie dodawane lub usuwane.
Można powiedzieć, że OOP jest paradygmatem „procesu na sztywno” i że wzorce projektowe są sposobami na uniknięcie tego paradygmatu. Ale na tym polega masowa personalizacja. Wzory projektowe ucieleśniają dynamiczne procesy w postaci niechlujnego twardego kodu. Po prostu nie ma sensu. Fakt, że F # pozwala na przekazywanie funkcji jako parametru oznacza, że zarówno języki funkcjonalne, jak i języki OOP próbują same dokonać masowej personalizacji.
Jak bardzo jest to mylące dla czytelnika, który stanowi kod, który reprezentuje skrypt? Wcale nie, jeśli uważasz, że konsumenci twojego kompilatora płacą za takie funkcje, ale dla mnie takie funkcje są marnotrawstwem semantycznym. Są bezcelowe, ponieważ celem masowego dostosowywania jest uczynienie samych procesów dynamicznymi , a nie tylko dynamicznymi dla programisty posługującego się Visual Studio.
źródło
Robi to, ponieważ wysokopoziomowy funkcjonalny PL (jak OCaml, z klasami, modułami itp.) Z pewnością zastępuje imperatywne języki OOP pod względem wszechstronności typów i siły wyrażania. Abstrakcje nie przeciekają, większość swoich pomysłów możesz wyrazić bezpośrednio w programie. Dlatego tak, zastępuje wzorce projektowe, które w większości są absurdalnie uproszczone w porównaniu do wzorców funkcjonalnych.
źródło