Co pozostaje takie samo? Jakie zmiany?
Wzory są takie same. Techniki językowe się zmieniają.
Czy istnieją zasady przewodnie, takie jak SOLID,
Tak. Rzeczywiście pozostają one zasadami przewodnimi. Nic się nie zmienia.
czy wzorce kanoniczne (być może zupełnie nowe), które powinien znać początkujący język dynamiczny?
Niektóre rzeczy są wyjątkowe. Głównie wpływa to na zmianę technik wdrażania.
Wzór jest - cóż - wzorem . To nie jest prawo. Nie podprogram. Nie makro. To tylko dobry pomysł, który się powtarza, ponieważ to dobry pomysł.
Dobre pomysły nie wychodzą z mody ani nie zmieniają się dramatycznie.
Inne notatki. Python nie jest „słabo napisany”. Jest silniej napisany niż Java lub C ++, ponieważ nie ma operacji rzutowania. [Tak, istnieje sposób, aby sfałszować klasę związaną z przedmiotem, ale nie jest to coś, co się robi, z wyjątkiem udowodnienia dziwnego, legalistycznego punktu.]
Również. Większość wzorców projektowych opiera się na różnych sposobach wykorzystania polimorfizmu.
Spójrz na państwa lub Dowództwa lub Memento jako przykłady. Mają hierarchie klas do tworzenia stanów polimorficznych, poleceń lub pamiątek zmian stanu. Nic nie zmienia się znacząco, gdy robisz to w Pythonie. Niewielkie zmiany obejmują złagodzenie dokładnej hierarchii klas, ponieważ polimorfizm w Pythonie zależy od powszechnych metod, a nie wspólnych przodków.
Ponadto niektóre wzory są po prostu próbą osiągnięcia późnego wiązania. Większość wzorców związanych z fabryką jest próbą umożliwienia łatwej zmiany hierarchii klas bez ponownej kompilacji każdego modułu C ++ w aplikacji. To nie jest tak interesująca optymalizacja w dynamicznym języku. Jednak Fabryka jako sposób na ukrycie szczegółów implementacji wciąż ma ogromną wartość.
Niektóre wzorce są próbą sterowania kompilatorem i konsolidatorem. Na przykład Singleton istnieje, aby tworzyć mylące globale, ale przynajmniej je kapsułkować. Singletonowe klasy Python nie są przyjemną perspektywą. Ale moduły Pythona są już singletonami, więc wielu z nas po prostu używa modułu i nie próbuje próbować zadzierać z klasą Singleton .
Peter Norvig podjął się tego samego pytania w 1998 r. Przeczytaj http://norvig.com/design-patterns/ppframe.htm, aby uzyskać zestaw szczegółowych rzeczy, które zauważył, oraz http://c2.com/cgi/wiki?AreDesignPatternsMissingLanguageFeatures dla dalsza dyskusja wokół tego punktu.
Krótka wersja jest taka, że gdy Twój język ma więcej funkcji, powtarzalne wzorce projektowe stają się prostsze - często nawet niewidoczne. Odkrył, że dotyczy to większości wzorców projektowych zidentyfikowanych przez GoF.
źródło
Programowanie w dynamicznym języku obiektowym wykorzystuje wiele takich samych wzorców i zasad, ale istnieją pewne poprawki i różnice związane z otoczeniem:
Zamień interfejsy na pisanie kaczek - tam, gdzie Gang of Four powiedziałby ci, abyś używał abstrakcyjnej klasy bazowej z czystymi funkcjami wirtualnymi, a ty używałbyś interfejsu w Javie, w dynamicznym języku, potrzebujesz tylko zrozumienia. Ponieważ możesz użyć dowolnego obiektu w dowolnym miejscu i będzie on działał dobrze, jeśli zaimplementuje metody, które są faktycznie wywoływane, nie musisz definiować formalnego interfejsu. Warto je udokumentować , aby było jasne, co jest rzeczywiście wymagane.
Funkcje to także obiekty - istnieje wiele wzorców dotyczących oddzielania decyzji od akcji; Dowodzenie, strategia, łańcuch odpowiedzialności itp. W języku z pierwszorzędnymi funkcjami często rozsądne jest po prostu przekazywanie funkcji zamiast tworzenia obiektów
.doIt()
metodami. Wzorce te przekształcają się w „użyj funkcji wyższego rzędu”.SPRZEDANY - Zasada segregacji interfejsu ma tutaj największe znaczenie, ponieważ nie ma interfejsów. Nadal powinieneś wziąć pod uwagę tę zasadę, ale nie możesz jej zweryfikować w swoim kodzie. Tylko osobista czujność ochroni cię tutaj. Z drugiej strony, ból spowodowany naruszeniem tej zasady jest znacznie zmniejszony w typowych środowiskach dynamicznych.
„... w moim szczególnym ... Idiomie!” - Każdy język ma dobre i złe praktyki, więc musisz się ich nauczyć i postępować zgodnie z nimi, jeśli chcesz mieć najlepszy kod w tych językach. Idealnie napisany wzorzec iteratora można na przykład wyśmiewać w języku z wbudowanym rozumieniem list.
źródło
Z mojego doświadczenia wynika, że niektóre wzorce są nadal przydatne w Pythonie, a nawet łatwiejsze w konfiguracji niż w bardziej statycznych językach. Niektóre Wzory OTOH są po prostu niepotrzebne, a nawet marszczone, jak Wzorzec Singleton. Zamiast tego użyj zmiennej lub funkcji na poziomie modułu. Lub użyj Wzoru Borga.
Zamiast konfigurować Wzorzec Kreatywny, często wystarczy przekazać dookoła wywołanie, które tworzy obiekty. Może to być funkcja, obiekt z
__call__
metodą lub nawet klasą, ponieważnew()
w Pythonie nie ma , tylko wywołanie samej klasy:Wzorzec stanu i strategii ma bardzo podobną strukturę w językach takich jak C ++ i Java. Mniej w Pythonie. Wzorzec strategii pozostaje mniej więcej taki sam, ale Wzorzec stanu staje się w większości niepotrzebny. Wzorzec stanu w językach statycznych symuluje zmianę klasy w czasie wykonywania. W Pythonie możesz to zrobić: zmienić klasę obiektu w czasie wykonywania. Tak długo, jak robisz to w kontrolowany, zamknięty sposób, wszystko powinno być w porządku:
Wzory oparte na statycznej wysyłce typów nie będą działać lub będą działać zupełnie inaczej. Nie musisz pisać zbyt dużo kodu płyty kotłowej, np. Wzorzec gościa: w Javie i C ++ musisz napisać metodę akceptacji w każdej odwiedzalnej klasie, natomiast w Pythonie możesz odziedziczyć tę funkcjonalność poprzez klasę mixin, np. Visitable:
Wiele sytuacji, które wymagają zastosowania Wzorca w Języku Statycznym, nie robi tego tak często w Pythonie. Wiele rzeczy można rozwiązać za pomocą innych technik, takich jak funkcje wyższego rzędu (dekoratorzy, fabryki funkcji) lub meta-klasy.
źródło
__class__
celu zaimplementowania fabryki w Pythonie jest dobrym pomysłem?