W każdym projekcie programistycznym menedżerowie z doświadczeniem w programowaniu starają się zabłysnąć, gdy zalecają pewne wzorce projektowe dla twojego projektu. Lubię wzorce projektowe, gdy mają sens lub gdy potrzebujesz skalowalnego rozwiązania. Na przykład korzystałem z wzorców proxy, obserwatorów i wzorców poleceń i robię to codziennie. Ale naprawdę waham się użyć powiedzenia wzorca fabrycznego, jeśli istnieje tylko jeden sposób na utworzenie obiektu, ponieważ fabryka może ułatwić to w przyszłości, ale komplikuje kod i jest czystym kosztem.
Tak więc moje pytanie dotyczy mojej przyszłej kariery i mojej odpowiedzi na typy menedżerów rzucające losowe nazwy wzorców wokół:
Jakich wzorów projektowych użyłeś, które ogólnie cię odrzuciły? Jakie są najgorsze wzorce projektowe , które należy wziąć pod uwagę, z wyjątkiem jednej sytuacji, w której mają one sens (czytaj: które wzorce projektowe są bardzo wąsko zdefiniowane)? (To tak, jak szukałem negatywnych recenzji ogólnie dobrego produktu Amazon, aby zobaczyć, co najbardziej wkurzyło ludzi w używaniu wzorów projektowych.) Nie mówię tu o Anty-Wzorach, ale o Wzorach, które zwykle są uważane za „dobre” wzory.
Edycja: Jak niektórzy odpowiedzieli, problemem jest najczęściej to, że wzorce nie są „złe”, ale „źle użyte”. Jeśli znasz wzory, które są często niewłaściwie używane lub nawet trudne w użyciu, pasują również jako odpowiedź.
Odpowiedzi:
Nie wierzę w złe wzorce, wierzę, że wzorce można źle zastosować!
W tej odpowiedzi wziąłem pod uwagę tylko wzorce GOF. Nie znam wszystkich możliwych wzorców wystarczająco dobrze, aby je również uwzględnić.
źródło
Oprócz Singletona i Odwiedzającego, o których wspominali już inni autorzy, nie znam „znanych” wzorów. Największe problemy IMHO nie wynikają z tego, że określony wzorzec projektowy jest „zły”, ale raczej z tego, że programiści stosują wzorce zbyt chętnie.
Prawie wszyscy przechodzą fazę „gorączki wzorcowej” podczas poznawania wzorców. Myśląc, że wzory są najlepsze od czasu krojonego chleba, początkowo próbuje się je stosować, gdy tylko widzi taką możliwość. Powoduje to, że kod zostaje zakopany pod wzorami, przy czym same wzorce już nie pomagają, po prostu utrudniają zrozumienie i utrzymanie kodu na dłuższą metę.
W końcu większość z nas przechodzi przez tę fazę i zaczyna uczyć się, jak używać wzorców do rozwiązywania prawdziwych problemów, a nie dla nich samych. Wzorce mają swoją cenę, co jest dodatkową złożonością, a zastosowanie dowolnego określonego wzorca jest uzasadnione tylko wtedy, gdy zwraca dodatkową złożoność, pomagając uprościć inną część systemu, dzięki czemu kod / konfiguracja ogólnie jest łatwiejsza do zrozumienia i utrzymania. Jeśli tak nie jest, często lepiej jest trzymać się z dala od wzorów, pozostając przy najprostszym rozwiązaniu, które może działać.
źródło
Mam zamiar wyjść tutaj na kończynę i zasugerować nadużywanie dziedziczenia. Zdecydowanie najbardziej odpowiedni w językach bez solidnej obsługi polimorfizmu w czasie kompilacji, takich jak Java. Dziedziczenie w czasie wykonywania jest narzędziem, a nie jakimś cudem dla jednej cechy.
Inni ludzie już wyrazili swoją podobną do mojej osobistej nienawiści do Singletonów, więc nie zamierzam tutaj o tym mówić.
źródło
Singel. Jest to wzorzec GOF, który jest obecnie częściej nazywany anty-wzorem. Jednym z powodów jest to, że Singleton utrudnia testowanie kodu.
źródło
:-)
Po wzorzec MVVM dla WPF zbyt ściśle, jak wskazano na przykład przez to pytanie . Niektóre osoby starają się postępować zgodnie z wytyczną, że żaden kod nie powinien być umieszczany w kodzie zbyt ściśle i wymyślają wszelkiego rodzaju egzotyczne hacki.
I oczywiście MVVM jest trudne jak diabli i po prostu nie jest tego warte w przypadku małych projektów krótkoterminowych.
Dr WPF napisał o tym ironiczny post w swoim artykule MV-poo .
źródło
Niektóre wzorce w książce GOF są specyficzne dla C ++, w tym sensie, że są mniej przydatne w językach z odbiciem, np. Wzorzec prototypowy jest mniej znaczący w Javie.
Uważam wzorzec interpretera za „wąski”. Musisz mieć ogólny problem, który wart jest opracowania ogólnego rozwiązania problemu. Działa tylko w przypadku specjalnych problemów, dla których możesz wymyślić język, zdefiniować gramatykę i napisać tłumacza. Przypadki problemowe powinny być reprezentowane jako zdanie w gramatyce. Nie sądzę, że często zdarza się takie sytuacje.
źródło
Ten, którego najczęściej żałuję (choć nie najbardziej gwałtownie): kiedy powinienem właśnie utworzyć funkcję, ale wdrożyłem rozwiązanie OOP.
źródło
Fabryka. Widziałem kod implementujący go, który tworzy tylko jeden typ. To całkowicie bezużyteczny kod IMO. Nie pomaga to, że wiele przykładów online jest całkowicie wymyślonych. Fabryka pizzy?
Być może fabryka jest łatwiejsza do przetestowania z powodu wstrzyknięcia zależności. Ale dodanie tego kodu, gdy go nie potrzebujesz, jest dla mnie bezcelowe, a argument testowy znika, gdy możesz użyć fałszywych frameworków, takich jak JMockit. Im łatwiej można stworzyć program, tym lepiej. Fabryki naprawdę mają sens tylko przy większej liczbie typów (przez większą, mam na myśli przynajmniej więcej niż 2).
źródło
Singel
Zgadzam się z innymi w sprawie Singletona. Nie dlatego, że nigdy nie powinieneś ich używać, tylko że powinno to być ograniczone do bardzo niewielu przypadków. Są one często używane jako leniwe globale.
Bezpieczeństwo wątków to jeden problem z singletonami. Obsługa wyjątków jest inna - jeśli singleton nie utworzy się poprawnie - nie zawsze wiesz, czy możesz bezpiecznie uchwycić błąd, szczególnie jeśli był to jeden z tych obiektów utworzonych „przed głównym”. A potem jest kwestia późniejszego sprzątania.
Wolę używać jednego singletona, a wszystkie inne „niedoszłe” singletony „subskrybują” twoje. Moim najczęstszym zastosowaniem singletonu jest obsługa zdarzenia „krzyczeć”: po prostu „transmitujesz na cały świat”, że wydarzenie miało miejsce, i każdy, kto go słucha, to zrobi. W ten sposób oddzielasz wydarzenia, które faktycznie mają miejsce, od tego, co ich słucha. (Rejestrowanie, sygnały itp.)
Gość
Brzydką rzeczą, którą o tym znajduję, poza tym, że programiści nie mogą wymyślić znaczących nazw i po prostu wywołują metody visit (), jest to, że dodaje rozszerzalność w jednym kierunku, a jednocześnie usuwa w innym, tj. Dodaje dodatkową funkcjonalność, ale ogranicza liczba obiektów, jakie odwiedzający muszą wiedzieć o wszystkich typach obiektów, które mogą odwiedzać.
Możliwe jest, choć niechlujne, zezwolenie na przedłużenie w obu kierunkach, ale nie wykorzystuje to całkowicie wzoru odwiedzającego w jego zwykłej formie. Najczęstszą aplikacją do tego jest drukowanie obiektów: istnieją różne sposoby drukowania obiektów i różne obiekty, które należy wydrukować. Powinieneś być w stanie rozszerzyć to w obu kierunkach. (Drukowanie oznacza dowolne przekształcanie obiektów w strumień: przechowywanie w pliku / zapisywanie w konsoli / GUI ... itp.).
(Uwaga: nie należy mylić tego z architekturą widoku dokumentu, która jest nieco innym wzorcem).
źródło
Myślę, że problem z niektórymi bardziej złożonymi wzorcami polega na tym, że jest ich tak wiele, że tracą one swoją wartość jako urządzenia komunikacyjne.
Najgorszym przestępcą, o jakim mogę myśleć w tej kategorii, jest wzór MVC. Nawet jeśli zignorujemy MVP, jest tak wiele odmian ról każdego z tych elementów, że musisz spędzić godzinę w każdym nowym systemie, zastanawiając się, gdzie leżą granice.
źródło
Nie ma złych wzorów, tylko źli ludzie.
Wolałbym odziedziczyć łatwo czytelny kod, który robi coś wyraźnego, ale jest trochę gadatliwy lub nie (kolejka złej muzyki villian) wielokrotnego użytku (łapanie oddechu!) Niż jakaś miszmasz
InheritAbstractTemplateFaucetSink<Kitchen>
.Kod wielokrotnego użytku jest świetny! Możliwe, że nie piszesz kodu, który zostanie ponownie użyty, lub ponowne napisanie podobnej logiki dla innej aplikacji zajmie Ci mniej czasu niż szalona próba ponownego użycia kodu innej aplikacji.
Aby dalej czytać, należy otworzyć część kodu C w rozsądnych implementacjach nagłówków posix lub clibs i odtworzyć wzór. Ten kod został napisany przez jednych z najmądrzejszych i najbardziej oddanych programistów na świecie. Czy wiesz, ile abstrakcyjnych wzorów fabrycznych zobaczysz? ... ŻADEN!. Jeszcze większe szanse są, jeśli zrozumiesz inne części tego, co się dzieje, znajdziesz logikę bardzo łatwą do zrozumienia i śledzenia.
Chodzi mi o to, że większość „wzorów” nie została stworzona w celu ulepszenia kodu, ale zostały stworzone do sprzedaży książek i oprogramowania do modelowania. Jeśli jesteś dobry w programowaniu, prawdopodobnie unikniesz większości z nich i napiszesz przejrzysty, zwięzły i sprytnie zaprojektowany kod, który rozwiąże twój problem. Gdy pojawi się kolejny problem, napiszesz przejrzysty, zwięzły, sprytnie zaprojektowany kod, aby go rozwiązać. Jeśli twoim celem jest napisanie mniej kodu, nie sądzę, że nie jesteś programistą. Uwielbiam pisać kod i chcę pisać tak dużo, jak to możliwe. Kiedy ponownie piszę coś, co już napisałem, robię to dziesiątki razy szybciej i pozbywam się wszystkich rzeczy, z których nie byłem zadowolony za pierwszym razem.
Dzięki temu zostawię ci prawdopodobnie najlepszy (odpowiedni) cytat z informatyki.
„ Istnieją dwa sposoby konstruowania projektu oprogramowania: Jednym ze sposobów jest uczynienie go tak prostym, aby oczywiście nie było braków, a drugim sposobem jest uczynienie go tak skomplikowanym, aby nie było oczywistych braków. Pierwsza metoda jest znacznie trudniejsza . ”
źródło
Zdecydowanie zgadzam się, że jest czas na większość wzorów i że możesz nadużywać wiele wzorów. Wiem, że najbardziej nadużywałem w przeszłości wzór szablonu abstrakcyjnego. W pełnym zakresie jest znany jako formularze internetowe ASP.NET.
źródło