Mój przyjaciel pracuje dla małej firmy nad projektem, którego każdy programista nienawidziłby: jest zmuszany do jak najszybszego zwolnienia, jest jedynym, który wydaje się dbać o dług techniczny, klient nie ma zaplecza technicznego itp.
Opowiedział mi historię, która kazała mi pomyśleć o stosowności wzorców projektowych w projektach takich jak ten. Oto historia.
Musieliśmy wyświetlać produkty w różnych miejscach na stronie. Na przykład menedżerowie treści mogą przeglądać produkty, ale także użytkowników końcowych lub partnerów za pośrednictwem interfejsu API.
Czasami brakowało informacji o produktach: na przykład kilka z nich nie miało żadnej ceny, gdy produkt został właśnie utworzony, ale cena nie została jeszcze określona. Niektóre nie miały opisu (opis jest złożonym obiektem z historiami modyfikacji, zlokalizowaną zawartością itp.). Niektórym brakowało informacji o wysyłce.
Zainspirowany moimi ostatnimi czytaniami o wzorach projektowych, pomyślałem, że to doskonała okazja do użycia magicznego wzoru Null Object . Zrobiłem to i wszystko było gładkie i czyste. Wystarczyło zadzwonić,
product.Price.ToString("c")
żeby wyświetlić cenę lubproduct.Description.Current
opis; nie są wymagane żadne warunki warunkowe. Aż pewnego dnia interesariusz poprosił o wyświetlenie go inaczej w interfejsie API, poprzeznull
użycie JSON. A także inaczej dla menedżerów treści, pokazując „Cena nieokreślona [Zmień]”. Musiałem zamordować mój ukochany wzór Null Object, ponieważ nie było już takiej potrzeby.W ten sam sposób musiałem usunąć kilka abstrakcyjnych fabryk i kilku budowniczych, w końcu zastąpiłem mój piękny wzór fasady bezpośrednimi i brzydkimi połączeniami, ponieważ podstawowe interfejsy zmieniały się dwa razy dziennie przez trzy miesiące, a nawet Singleton mnie opuścił kiedy wymagania mówiły, że dany obiekt musiał być inny w zależności od kontekstu.
Ponad trzy tygodnie pracy polegały na dodawaniu wzorców projektowych, a następnie ich rozerwaniu miesiąc później, a mój kod w końcu stał się na tyle spaghetti, że nikt, w tym ja, nie może go utrzymać. Czy nie lepiej byłoby nigdy nie używać tych wzorów?
Rzeczywiście musiałem popracować nad projektami, w których wymagania ciągle się zmieniają i są podyktowane przez osoby, które tak naprawdę nie mają na myśli spójności ani spójności produktu. W tym kontekście nie ma znaczenia, jak zwinny jesteś, otrzymasz eleganckie rozwiązanie problemu, a kiedy go w końcu wdrożysz, dowiesz się, że wymagania zmieniły się tak drastycznie, że Twoje eleganckie rozwiązanie nie pasuje już dłużej.
Jakie byłoby rozwiązanie w tym przypadku?
Nie używasz żadnych wzorców projektowych, przestajesz myśleć i piszesz kodu bezpośrednio?
Interesujące byłoby doświadczenie, w którym zespół pisze kod bezpośrednio, podczas gdy inny zastanawia się dwa razy przed pisaniem, ryzykując wyrzucenie oryginalnego projektu kilka dni później: kto wie, może obie drużyny miałyby ten sam dług techniczny. W przypadku braku takich danych twierdziłbym jedynie, że pisanie kodu bez uprzedniego myślenia podczas pracy nad projektem trwającym 20 miesięcy nie wydaje się właściwe .
Utrzymać wzorzec projektowy, który nie ma już sensu, i spróbować dodać więcej wzorców dla nowo utworzonej sytuacji?
To też nie wydaje się właściwe. Wzory są używane w celu uproszczenia zrozumienia kodu; umieścić zbyt wiele wzorców, a kod stanie się bałaganem.
Czy zaczniesz myśleć o nowym projekcie, który obejmuje nowe wymagania, a następnie powoli przebudujesz stary projekt na nowy?
Jako teoretyk i ten, który faworyzuje Agile, jestem całkowicie w to zaangażowany. W praktyce, gdy wiesz, że będziesz musiał co tydzień wracać do tablicy i przerabiać większą część poprzedniego projektu, a klient po prostu nie ma wystarczających środków, aby ci za to zapłacić, ani wystarczająco dużo czasu, aby czekać , to prawdopodobnie nie zadziała.
Jakieś sugestie?
źródło
Odpowiedzi:
Widzę kilka błędnych założeń w tym pytaniu:
Wzory projektowe nie są celem samym w sobie, powinny ci służyć, a nie odwrotnie. Jeśli wzorzec projektowy nie ułatwia implementacji kodu, a przynajmniej lepiej go rozwija (co oznacza: łatwiejszy do dostosowania do zmieniających się wymagań), wówczas wzorzec nie spełnia swojego celu. Nie stosuj wzorców, gdy nie ułatwiają „życia” zespołowi. Jeśli nowy wzorzec obiektu Null służył Twojemu znajomemu przez czas, w którym go używał, wszystko było w porządku. Jeśli miałoby to zostać później wyeliminowane, mogłoby to być również w porządku. Jeśli wzorzec obiektu zerowego spowolnił (poprawną) implementację, wówczas jego użycie było nieprawidłowe. Zauważ, że z tej części historii nie można do tej pory wyciągać wniosków na temat „kodu spaghetti”.
To nie jest ani jego praca, ani jego wina! Twoim zadaniem jest dbanie o spójność i spójność. Gdy wymagania zmieniają się dwa razy dziennie, rozwiązaniem nie powinno być poświęcenie jakości kodu. Po prostu powiedz klientowi, jak długo to potrwa, a jeśli uważasz, że potrzebujesz więcej czasu, aby uzyskać właściwy projekt, dodaj wystarczająco duży margines bezpieczeństwa do każdej oceny. Zwłaszcza, gdy klient próbuje wywierać na ciebie presję, skorzystaj z „zasady Scotty” . A kiedy spieramy się z klientem nietechnicznym o wysiłku, unikaj pojęć takich jak „refaktoryzacja”, „testy jednostkowe”, „wzorce projektowe” lub „dokumentacja kodu” - to rzeczy, których nie rozumie i prawdopodobnie uważa za „niepotrzebne” bzdury ”, ponieważ nie widzi w tym żadnej wartości. lub przynajmniej zrozumiałe dla klienta (funkcje, funkcje podrzędne, zmiany zachowania, dokumenty użytkownika, poprawki błędów, optymalizacja wydajności itd.).
Szczerze mówiąc, jeśli „podstawowe interfejsy zmieniają się dwa razy dziennie przez trzy miesiące”, rozwiązaniem nie powinno być reagowanie poprzez zmianę kodu dwa razy dziennie. Prawdziwym rozwiązaniem jest pytanie, dlaczego wymagania zmieniają się tak często i czy można dokonać zmiany w tej części procesu. Może pomoże trochę więcej wstępnych analiz. Być może interfejs jest zbyt szeroki, ponieważ granica między komponentami jest źle wybrana. Czasami pomaga poprosić o więcej informacji na temat tego, która część wymagań jest stabilna, a która jest nadal przedmiotem dyskusji (i faktycznie opóźnia wdrożenie w odniesieniu do omawianych kwestii). A czasem niektórzy ludzie muszą zostać „wyrzuceni w tyłek” za to, że nie zmieniają zdania dwa razy dziennie.
źródło
Moim skromnym zdaniem jest to, że nie należy unikać wzorców projektowych ani ich unikać.
Wzory projektowe są po prostu dobrze znanymi i zaufanymi rozwiązaniami ogólnych problemów, którym nadano nazwy. Nie różnią się one pod względem technicznym od innych rozwiązań lub projektów, o których można pomyśleć.
Myślę, że źródłem problemu może być to, że twój przyjaciel myśli w kategoriach „zastosowania lub niestosowania wzorca projektowego”, zamiast myślenia w kategoriach „najlepszego rozwiązania, jakie mogę wymyślić, w tym między innymi wzorców Wiem".
Być może takie podejście prowadzi go do używania wzorów w częściowo sztuczny lub wymuszony sposób, w miejscach, do których nie należą. I to powoduje bałagan.
źródło
W twoim przykładzie użycia wzorca Null Object uważam, że ostatecznie się nie udał, ponieważ spełnił potrzeby programisty, a nie potrzeby klienta. Klient musiał wyświetlić cenę w formie odpowiedniej do kontekstu. Programista musiał uprościć część kodu wyświetlacza.
A zatem, jeśli wzór nie spełnia wymagań, czy mówimy, że wszystkie wzory są stratą czasu, czy mówimy, że potrzebujemy innego wzoru?
źródło
Wygląda na to, że błędem było raczej usunięcie obiektów wzoru niż ich użycie. W pierwotnym projekcie wydaje się, że obiekt zerowy dostarczył rozwiązanie problemu. To może nie być najlepsze rozwiązanie.
Jako jedyna osoba pracująca nad projektem masz szansę doświadczyć całego procesu rozwoju. Dużą wadą jest brak kogoś, kto będzie twoim mentorem. Poświęcenie czasu na naukę i stosowanie najlepszych lub lepszych praktyk może się szybko zwrócić. Sztuczka polega na określeniu, której praktyki się nauczyć.
Łańcuchy referencyjne w formie product.Price.toString („c”) naruszają prawo Demeter . Widziałem wiele problemów związanych z tą praktyką, z których wiele dotyczy zer. Metoda taka jak product.displayPrice („c”) może wewnętrznie obsługiwać ceny zerowe. Podobnie product.Description.Current może być obsługiwany przez product.displayDescription (), product.displayCurrentDescription (). lub product.diplay („Bieżący”).
Reakcja na nowy wymóg dla menedżerów i dostawców treści musi być realizowana poprzez reagowanie na kontekst. Istnieje wiele różnych podejść, które można zastosować. Metody fabryczne mogą wykorzystywać różne klasy produktów w zależności od klasy użytkownika, w której będą wyświetlane. Innym podejściem byłoby opracowanie metod wyświetlania klas produktów w celu tworzenia różnych danych dla różnych użytkowników.
Dobra wiadomość jest taka, że przyjaciel zdaje sobie sprawę, że sprawy wymykają się spod kontroli. Mam nadzieję, że ma kod w kontroli wersji. Pozwoli mu to wycofać się z złych decyzji, które niezmiennie będzie podejmował. Częścią uczenia się jest wypróbowanie różnych metod, z których niektóre się nie powiodą. Jeśli uda mu się poradzić sobie przez kilka następnych miesięcy, może znaleźć rozwiązania upraszczające jego życie i posprzątać spaghetti. Mógłby spróbować naprawić jedną rzecz każdego tygodnia.
źródło
Pytanie wydaje się błędne w tak wielu punktach. Ale te rażące to:
Wiele osób słusznie stwierdziło, że wzorce projektowe w dużej mierze dotyczą etykietowania i nazywania powszechnej praktyki. Pomyśl więc o koszuli, koszula ma kołnierzyk, z jakiegoś powodu zdejmujesz kołnierz lub jego część. Nazwy i etykiety zmieniają się, ale nadal jest to w istocie koszula. Dokładnie tak jest tutaj, drobne zmiany w szczegółach, co nie oznacza, że „zamordowałeś” ten wzór. (znowu pamiętaj o ekstremalnych sformułowaniach)
Z mojego doświadczenia wynika, że gdy pojawiają się niewielkie wymagania, wystarczy zmienić tylko niewielką część bazy kodu. Niektóre mogą być nieco zuchwałe, ale nic zbyt poważnego, aby znacząco wpłynąć na łatwość konserwacji lub czytelność, a często wystarczy kilka linii komentarza, aby wyjaśnić hackerską część. Jest to również bardzo powszechna praktyka.
źródło
Zatrzymajmy się na chwilę i spójrzmy na podstawową kwestię tutaj - zaprojektowanie systemu, w którym model architektury jest zbyt sprzężony z funkcjami niskiego poziomu w systemie, powodując częstą awarię architektury w procesie programowania.
Myślę, że musimy pamiętać, że wykorzystanie architektury i wzorców projektowych z tym związanych należy ułożyć na odpowiednim poziomie, a analiza właściwego poziomu nie jest trywialna. Z jednej strony możesz łatwo utrzymać architekturę systemu na zbyt wysokim poziomie z jedynie bardzo podstawowymi ograniczeniami, takimi jak „MVC” lub podobnymi, co może prowadzić do utraty szans, takich jak jasne wytyczne i dźwignia kodu oraz gdzie kod spaghetti może łatwo rozkwitać w całej tej wolnej przestrzeni.
Z drugiej strony możesz równie dobrze nad-architekturować swój system, jak ustawiając ograniczenia na szczegółowy poziom, przy założeniu, że możesz polegać na ograniczeniach, które w rzeczywistości są bardziej niestabilne, niż się spodziewasz, stale przełamując ograniczenia i zmuszając cię do ciągłej przebudowy i odbudowy, aż zaczniesz rozpaczać.
Zmiany wymagań dotyczących systemu zawsze będą istnieć, w mniejszym lub większym stopniu. Potencjalne korzyści wynikające ze stosowania architektury i wzorców projektowych zawsze będą istnieć, więc tak naprawdę nie ma kwestii korzystania z wzorców projektowych, ale na jakim poziomie powinieneś ich używać.
Wymaga to nie tylko zrozumienia aktualnych wymagań proponowanego systemu, ale także określenia, jakie aspekty można uznać za stabilne podstawowe właściwości systemu i jakie właściwości mogą ulec zmianie w trakcie rozwoju.
Jeśli okaże się, że ciągle musisz walczyć z niezorganizowanym kodem spaghetti, prawdopodobnie nie robisz wystarczającej architektury lub na wysokim poziomie. Jeśli zauważysz, że twoja architektura często się psuje, prawdopodobnie robisz zbyt szczegółową architekturę.
Wykorzystanie architektury i wzorów projektowych nie jest czymś, co można po prostu „pokryć” systemem, tak jakbyś malował biurko. Są to techniki, które należy stosować z rozwagą, na poziomie, na którym ograniczenia muszą polegać, mają dużą możliwość zachowania stabilności, i gdzie te techniki rzeczywiście są warte kłopotu z modelowaniem architektury i wdrażaniem rzeczywistych ograniczeń / architektury / wzorców jako kod.
Odnosząc się do kwestii zbyt szczegółowej architektury, równie dobrze można włożyć dużo wysiłku w architekturę, w której nie przynosi ona dużej wartości. Zobacz architekturę opartą na ryzyku w celach informacyjnych, podoba mi się ta książka - wystarczy architektury oprogramowania , może ty też.
Edytować
Wyjaśniłem swoją odpowiedź, ponieważ zdałem sobie sprawę, że często wyrażałem się jako „zbyt dużo architektury”, gdzie naprawdę miałem na myśli „zbyt szczegółową architekturę”, co nie jest dokładnie takie samo. Zbyt szczegółowa architektura może być często postrzegana jako „zbyt duża” architektura, ale nawet jeśli utrzymasz architekturę na dobrym poziomie i stworzysz najpiękniejszy system, jaki ludzkość kiedykolwiek widziała, może to być zbyt duży wysiłek w architekturze, jeśli jej priorytetami są na temat funkcji i czasu wprowadzenia na rynek.
źródło
Twój przyjaciel wydaje się mieć do czynienia z licznymi przeciwnościami wiatru na podstawie swojej anegdoty. Jest to niefortunne i może być bardzo trudnym środowiskiem do pracy. Mimo trudności był na właściwej ścieżce, używając wzorów, aby ułatwić sobie życie, i szkoda, że opuścił tę ścieżkę. Kod spaghetti to najlepszy wynik.
Ponieważ istnieją dwa różne obszary problemów, techniczne i interpersonalne, zajmę się każdym z nich osobno.
Interpersonalne
Zmagania twojego przyjaciela dotyczą szybko zmieniających się wymagań i tego, jak wpływa to na jego zdolność do pisania łatwego do utrzymania kodu. Najpierw powiedziałbym, że wymagania zmieniające się dwa razy dziennie, każdego dnia przez tak długi okres czasu, stanowią większy problem i mają nierealistyczne domniemane oczekiwania. Wymagania zmieniają się szybciej niż kod może się zmienić. Nie możemy oczekiwać, że kod lub programista dotrzymają kroku. To szybkie tempo zmian jest objawem niepełnej koncepcji pożądanego produktu na wyższym poziomie. To jest problem. Jeśli nie wiedzą, czego naprawdę chcą, będą marnować dużo czasu i pieniędzy, aby nigdy tego nie uzyskać.
Dobrze jest ustawić granice zmian. Grupuj razem zmiany w zestawy co dwa tygodnie, a następnie zamrażaj je na dwa tygodnie podczas ich wdrażania. Utwórz nową listę na następne dwa tygodnie. Mam wrażenie, że niektóre z tych zmian nakładają się lub są ze sobą sprzeczne (np. Wahanie między dwiema opcjami). Kiedy zmiany nadchodzą szybko i wściekle, wszystkie mają najwyższy priorytet. Jeśli pozwolisz im zgromadzić się na liście, możesz z nimi współpracować w celu uporządkowania i ustalenia priorytetów tego, co najważniejsze, aby zmaksymalizować wysiłki i wydajność. Mogą zobaczyć, że niektóre z ich zmian są głupie lub mniej ważne, co daje Twojemu przyjacielowi chwilę wytchnienia.
Te problemy nie powinny jednak powstrzymywać Cię przed pisaniem dobrego kodu. Zły kod prowadzi do gorszych problemów. Refaktoryzacja jednego rozwiązania może wymagać czasu, ale sam fakt, że jest to możliwe, pokazuje zalety dobrych praktyk kodowania dzięki wzorcom i zasadom.
W warunkach częstych zmian w pewnym momencie pojawi się dług techniczny . O wiele lepiej jest dokonywać płatności w tym kierunku niż wrzucać ręcznik i czekać, aż stanie się zbyt duży, aby go pokonać. Jeśli wzorzec nie jest już użyteczny, przerób go, ale nie wracaj do kodowania kowbojów.
Techniczny
Twój przyjaciel zdaje się dobrze orientować w podstawowych wzorach projektowych. Obiekt zerowy to dobre podejście do problemu, z którym się borykał. W rzeczywistości jest to nadal dobre podejście. Tam, gdzie wydaje się, że ma on wyzwania, rozumie zasady leżące u podstaw tych wzorów, dlaczego tak naprawdę są. W przeciwnym razie nie sądzę, by porzucił swoje podejście.
(Poniżej znajduje się zestaw rozwiązań technicznych, o które nie pytano w pierwotnym pytaniu, ale które pokazują, w jaki sposób możemy zastosować wzorce w celach ilustracyjnych).
Zasada stojąca za obiektem zerowym polega na kapsułkowaniu tego, co różne . Ukrywamy jakie zmiany, więc nie musimy zajmować się tym wszędzie. W tym przypadku obiekt zerowy zawierał wariancję w
product.Price
instancji (nazwiemy goPrice
obiektem, a cena obiektu zerowego będzie wynosićNullPrice
).Price
to obiekt domeny, koncepcja biznesowa. Czasami w naszej logice biznesowej nie znamy jeszcze ceny. To się stało. Idealny przypadek użycia dla obiektu zerowego.Price
s mająToString
metodę, która wyprowadza cenę lub pusty ciąg, jeśli nie jest znany (lubNullPrice#ToString
zwraca pusty ciąg). To rozsądne zachowanie. Potem zmieniają się wymagania.Musimy wyprowadzić
null
do widoku API lub inny ciąg do widoku menedżerów. Jak to wpływa na naszą logikę biznesową? Tak nie jest. W powyższym stwierdzeniu dwukrotnie użyłem słowa „widok”. To słowo prawdopodobnie nie zostało wypowiedziane wprost, ale musimy ćwiczyć, aby usłyszeć ukryte słowa w wymaganiach. Dlaczego więc „widok” ma tak duże znaczenie? Ponieważ mówi nam, gdzie naprawdę musi nastąpić zmiana: naszym zdaniem.Poza tym : to, czy używamy frameworka MVC, nie ma tutaj znaczenia. Chociaż MVC ma bardzo specyficzne znaczenie dla „Widoku”, używam go w bardziej ogólnym (i być może bardziej stosownym) znaczeniu fragmentu kodu prezentacji.
Naprawdę musimy to naprawić w widoku. Jak możemy to zrobić? Najłatwiejszym sposobem na to byłoby
if
stwierdzenie. Wiem, że obiekt zerowy miał pozbyć się wszystkich ifs, ale musimy być pragmatyczni. Możemy sprawdzić ciąg znaków, aby zobaczyć, czy jest pusty, i przełączyć:Jak to wpływa na enkapsulację? Najważniejsze jest tutaj to, że logika widoku jest zamknięta w widoku . W ten sposób możemy całkowicie odizolować nasze obiekty logiki biznesowej / domeny od zmian w logice widoku. Jest brzydka, ale działa. Nie jest to jednak jedyna opcja.
Moglibyśmy powiedzieć, że nasza logika biznesowa zmieniła się tylko trochę, ponieważ chcemy wyprowadzać domyślne łańcuchy, jeśli nie zostanie ustawiona żadna cena. Możemy dokonać drobnych poprawek w naszej
Price#ToString
metodzie (faktycznie stworzyć przeciążoną metodę). Możemy zaakceptować domyślną wartość zwrotu i zwrócić, że jeśli nie zostanie ustalona cena:A teraz nasz kod widoku staje się:
Warunek zniknął. Jednak zbyt częste wykonywanie tej czynności może spowodować rozprzestrzenianie specjalnych metod tworzenia przypadków w obiektach domeny, więc ma to sens tylko wtedy, gdy wystąpi tylko kilka takich przypadków.
Zamiast tego możemy utworzyć
IsSet
metodę,Price
która zwraca wartość logiczną:Zobacz logikę:
Widzimy powrót warunku w widoku, ale sprawa jest silniejsza w przypadku logiki biznesowej, która mówi, czy cena jest ustawiona. Teraz możemy go używać
Price#IsSet
gdzie indziej, skoro mamy go dostępnego.Wreszcie możemy zawrzeć pomysł przedstawienia ceny całkowicie w pomocniku dla widoku. To ukryłoby warunek, jednocześnie zachowując obiekt domeny tak bardzo, jak byśmy tego chcieli:
Zobacz logikę:
Istnieje wiele innych sposobów dokonywania zmian (możemy uogólnić
PriceStringHelper
na obiekt, który zwraca wartość domyślną, jeśli ciąg jest pusty), ale są to kilka szybkich, które zachowują (w przeważającej części) zarówno wzorce, jak i zasady, ponieważ a także pragmatyczny aspekt dokonania takiej zmiany.źródło
Złożoność wzoru projektowego może cię ugryźć, jeśli problem, który miał rozwiązać, nagle zniknie. Niestety, ze względu na entuzjazm i popularność wzorców projektowych, ryzyko to rzadko jest jawne. Anegdota twojego przyjaciela bardzo pomaga pokazać, w jaki sposób wzory się nie opłacają. Jeff Atwood ma kilka wybranych słów na ten temat.
Dokumentuj punkty zmienności (są to ryzyka) w wymaganiach
Wiele bardziej złożonych wzorców projektowych (nie tyle Null Object) zawiera koncepcję odmian chronionych , to znaczy „Zidentyfikuj punkty przewidywanej zmienności lub niestabilności; przydziel obowiązki, aby stworzyć wokół nich stabilny interfejs”. Adapter, gość, fasada, warstwy, obserwator, strategia, dekorator itp. Wykorzystują tę zasadę. „Opłacają się”, gdy oprogramowanie musi zostać rozszerzone w zakresie oczekiwanej zmienności, a „stabilne” założenia pozostają stabilne.
Jeśli twoje wymagania są tak niestabilne, że twoje „przewidywane odmiany” są zawsze błędne, wówczas zastosowane wzorce spowodują ból lub co najwyżej niepotrzebną złożoność.
Craig Larman mówi o dwóch możliwościach zastosowania odmian chronionych:
Oba powinny być udokumentowane przez programistów, ale prawdopodobnie powinieneś mieć zaangażowanie klientów w punkty zmienności.
Aby zarządzać ryzykiem, można powiedzieć, że każdy wzór projektowy wykorzystujący PV powinien być przypisany do punktu zmienności wymagań podpisanych przez klienta. Jeśli klient zmieni punkt zmienności w wymaganiach, Twój projekt może wymagać radykalnej zmiany (ponieważ prawdopodobnie zainwestowałeś w projekt [wzorce] w celu obsługi tej zmiany). Nie trzeba wyjaśniać spójności, sprzężenia itp.
Na przykład klient chce, aby oprogramowanie współpracowało z trzema różnymi starszymi systemami inwentaryzacji. To punkt zmienności, który projektujesz. Jeśli klient nie spełni tego wymogu, to oczywiście masz wiele niepotrzebnej infrastruktury projektowej. Klient musi wiedzieć, że punkty zmienności kosztują coś.
CONSTANTS
w kodzie źródłowym są prostą formą PVInną analogią do twojego pytania byłoby pytanie, czy
CONSTANTS
dobrym pomysłem jest użycie w kodzie źródłowym. Nawiązując do tego przykładu , powiedzmy, że klient zrezygnował z hasła. Tak więcMAX_PASSWORD_SIZE
ciągłe rozprzestrzenianie się w całym kodzie stałoby się bezużyteczne, a nawet utrudniałoby konserwację i czytelność. Czy obwiniłbyś użycieCONSTANTS
tego powodu?źródło
Myślę, że przynajmniej częściowo zależy to od charakteru twojej sytuacji.
Wspominałeś o ciągle zmieniających się wymaganiach. Jeśli klient mówi: „Chcę, aby ta aplikacja do pszczół działała również z osami”, wydaje się, że to taka sytuacja, w której staranne projektowanie pomogłoby w rozwoju, a nie utrudniało (szczególnie, jeśli weźmie się pod uwagę, że w przyszłości może chcieć trzymaj też muszki owocowe).
Z drugiej strony, jeśli charakter zmiany przypomina bardziej: „Chcę, aby ta aplikacja pszczół zarządzała listą płac mojego konglomeratu pralni”, żadna ilość kodu nie wykopie cię z dziury.
Wzory projektowe nie mają z natury nic dobrego. Są narzędziami jak każde inne - używamy ich tylko w celu ułatwienia naszej pracy w średnim i długim okresie. Jeśli inne narzędzie (takie jak komunikacja lub badania ) jest bardziej przydatne, wówczas go używamy.
źródło