Projektuj przyszłe zmiany lub rozwiązuj problem [zamknięty]

37

Pisząc kod lub podczas projektowania, próbujesz uogólnić problem w pierwszej instancji lub rozwiązać bardzo specyficzny problem.

Pytam o to, ponieważ próba uogólnienia problemu komplikuje rzeczy (co może nie być konieczne), az drugiej strony bardzo trudno będzie rozszerzyć konkretne rozwiązanie, jeśli nastąpi zmiana w wymaganiu.

Myślę, że rozwiązaniem jest znalezienie środkowej ścieżki, którą łatwiej powiedzieć niż zrobić. Jak radzisz sobie z tego rodzaju problemem? Jeśli zaczniesz uogólniać to, w którym momencie wiesz, że taka część uogólnienia jest wystarczająca?

Naveen
źródło
To nasuwa bardzo ważne pytanie: czy naprawdę możesz przewidzieć, jak zmienią się wymagania?
user16764 17.10.13
Wielu ludzi powie ci YAGNI. To ludzie, którymi gardzisz, kiedy musisz przejąć ich pracę.
Martin Maat,

Odpowiedzi:

60

Zbyt często, gdy próbujesz projektować na przyszłość, twoje przewidywania dotyczące przyszłych potrzeb okazują się błędne. Zwykle lepiej jest zrefaktoryzować, kiedy faktycznie wiesz, jak zmieniły się potrzeby, niż przeprojektować swój system pierwszego dnia. Jednocześnie nie strzelaj też w stopę. Z pewnością jest środek, a wiedza, gdzie to jest, to więcej sztuki niż nauki.

Sprowadzając to do jednej ogólnej zasady: mniej znaczy więcej.


źródło
17
+1 „Przyszłość nie jest już taka, jak kiedyś”.
Dan Lyons
19

Czy znasz Agile? Jedną z głównych zasad Agile jest YAGNI . Uważam, że to najlepszy sposób na podejście.

„Nie będziesz go potrzebować” ... to zasada ekstremalnego programowania (XP), która mówi, że programista nie powinien dodawać funkcjonalności, dopóki nie zostanie uznany za konieczny. Ron Jeffries pisze: „Zawsze wdrażaj rzeczy, kiedy ich naprawdę potrzebujesz, nigdy, gdy tylko przewidujesz, że ich potrzebujesz”.

... YAGNI jest zasadą stojącą za praktyką XP polegającą na „robieniu najprostszej rzeczy, która mogłaby ewentualnie działać” (DTSTTCPW). Jest przeznaczony do stosowania w połączeniu z kilkoma innymi praktykami, takimi jak ciągłe refaktoryzowanie , ciągłe automatyczne testy jednostkowe i ciągła integracja . Zastosowanie bez ciągłego refaktoryzacji może prowadzić do bałaganu i ogromnej przeróbki. Ciągłe refaktoryzowanie z kolei polega na zautomatyzowanych testach jednostkowych jako siatce bezpieczeństwa (w celu wykrycia nieprzewidzianych błędów) i ciągłej integracji, aby zapobiec szerszym problemom z integracją ...

YAGNI nie jest powszechnie akceptowana jako ważna zasada, nawet w połączeniu z praktykami wspierającymi. Konieczność połączenia go z praktykami wspierającymi zamiast samodzielnego używania jest częścią oryginalnej definicji XP ...

Matt Grande
źródło
3
Chociaż zgadzam się mniej więcej z YAGNI, nie mogę tego znaleźć w zwinnych zasadach: agilemanifesto.org/principles.html
Jens Schauder
„Prostota - sztuka maksymalizacji ilości niewykonanej pracy - jest niezbędna” miałoby zastosowanie do YAGNI i niektórych innych zwinnych praktyk.
tvanfosson
1
Chociaż w manifeście nie jest wyraźnie napisane „YAGNI”, myślę, że są one bardzo zgodne ze sobą.
2
@Jens i @Matt, YAGNI, pracują w trybie zwinnym dzięki pakietowi XP jako metodologii zwinnej. Jak wspomniano w artykule w Wikipedii, zasada JAGNI została opracowana przez Rona Jeffriesa w ramach podstawowych praktyk XP.
1
Być może YAGNI jest idiomem programistów, ale TDD jest tym, który całkiem ładnie stosuje ten dylemat. W kroku, w którym jest napisane, że powinieneś napisać tylko tyle kodu, aby przejść test i nie więcej. A TDD jest częścią zwinności.
Robert Koritnik
12

Jest to prawdopodobnie jedna z najtrudniejszych części tworzenia oprogramowania, ponieważ musisz przejść między „YAGNI” a „PYIAC” (Paint Your Into A Corner).

Łatwo jest powiedzieć „nie pisz funkcji, chyba że jej potrzebujesz”. Trudność polega na zaprojektowaniu kodu, aby można było łatwo dodawać funkcje później, gdy ich potrzebujesz.

Kluczem jest możliwość zaprojektowania architektury rozszerzalnej, w której nie piszesz więcej kodu niż potrzebujesz. Umiejętność zrobienia tego dobrze pochodzi z całego doświadczenia (i bólu).

17 z 26
źródło
7

Poświęcam trochę czasu na myślenie o ogólnym kierunku projektowania - nie za dużo, ale wystarczająco, aby w zasadzie naszkicować ogólny zarys. Następnie stosuję metodykę zwinną opartą na historii, używając TDD, aby opracować rozwiązania dla poszczególnych historii. Wdrażając za pośrednictwem TDD, pamiętam o moim ogólnym przeglądzie i (a) kieruję moimi konkretnymi implementacjami, aby podążały za ogólnym przeglądem lub (b) refaktoryzowałem (i poprawiałem) moje zrozumienie / kierunek na wysokim poziomie w oparciu o czego uczę się podczas testowania / wdrażania.

Wydaje mi się, że błędem jest nie planować z góry, ale prawdopodobnie jest to zbyt duży problem. Tak bardzo, jak to możliwe, chciałbym pozwolić, aby doświadczenie poprowadziło mnie na dużym obrazie, a następnie pozwól, aby projekt rozwijał się organicznie zgodnie z wytycznymi, które postanowiłem opracować. Korzystając z TDD, stwierdzam, że sam projekt jest zmuszony do przyjęcia lepszych zasad projektowania (oddzielone, pojedyncza odpowiedzialność itp.) I jest bardziej podatny na zmiany w stosunku do zmian, niż gdybym starał się wstępnie wyobrazić sobie całość i dopasować do niej rozwój.

tvanfosson
źródło
3

Dobry projekt uwzględnia przyszłe zmiany i zdecydowanie warto po niego sięgnąć. Rozważ system operacyjny UNIX i jego „wszystko jest filozofią plików”. Ta decyzja projektowa została podjęta nie w celu zaspokojenia pilnej potrzeby, ale z myślą o przyszłych wymaganiach. Drżą na myśl, jak wyglądałby system operacyjny oparty na zwinnej konstrukcji.


źródło
2

To, z czym próbujesz sobie poradzić, wiąże się z ponownym użyciem (tj. Uogólnieniem problemu, z którym masz teraz do czynienia, abyś mógł ponownie wykorzystać pracę (kod) w przyszłości). Mówiłem to wcześniej i będę odwołują się do niego ponownie.

Wydaje mi się, że słyszałem, jak inni mówią coś na temat:

Rozwiązuję problem za pierwszym razem. Kiedy powtarzam moje rozwiązanie po raz pierwszy, odnotowuję to. Kiedy powtarzam to ponownie, refaktoryzuję.

Jason Punyon
źródło
2

Projekt dla „teraz + 1”. Oznacza to, że rozwiąż natychmiastowy problem i zbuduj wystarczającą funkcjonalność, aby następnym razem poprosić o zmianę, już masz ją w połowie (lub więcej) i masz wybór: a) natychmiastowe rozwiązanie problemu i refaktoryzacja później lub b) rozwiązanie „teraz + 1” ponownie (z wykonaniem połowy „teraz”)

To zależy od projektu i, krótko mówiąc, doświadczenie nauczy Cię, czym jest „+1”.

Richard Levasseur
źródło
1

Filozofię YAGNI , której nie potrzebujesz, można podsumować (z artykułu):

Według tych, którzy opowiadają się za podejściem YAGNI, pokusa pisania kodu, który nie jest w tej chwili potrzebny, ale może być w przyszłości, ma następujące wady:

  • Czas poświęcony jest na dodawanie, testowanie lub ulepszanie niezbędnej funkcjonalności.
  • Nowe funkcje muszą być debugowane, dokumentowane i obsługiwane.
  • Każda nowa funkcja nakłada ograniczenia na to, co można zrobić w przyszłości, więc niepotrzebna funkcja może uniemożliwić późniejsze wdrożenie koniecznej funkcji.
  • Dopóki ta funkcja nie jest faktycznie potrzebna, trudno jest w pełni zdefiniować, co powinna zrobić i przetestować. Jeśli nowa funkcja nie zostanie poprawnie zdefiniowana i przetestowana, może nie działać poprawnie, nawet jeśli w końcu będzie potrzebna.
  • Prowadzi to do wzdęcia kodu; oprogramowanie staje się większe i bardziej skomplikowane.
  • Jeśli nie ma specyfikacji i kontroli wersji, funkcja ta może nie być znana programistom, którzy mogliby z niej skorzystać.
  • Dodanie nowej funkcji może sugerować inne nowe funkcje. Jeśli te nowe funkcje zostaną również zaimplementowane, może to spowodować efekt śnieżki w kierunku pełzającego featuryzmu.
JeffH
źródło
0

Jestem wielkim zwolennikiem projektowania danego problemu i nie wysadzam twojego projektu, próbując odgadnąć wszystkie przypadki, które musisz uwzględnić, ponieważ „pewnego dnia możemy go potrzebować”.

Zasadniczo, biorąc pod uwagę listę konkretnych wymagań, zaprojektuj w oparciu o to, nie oznacza to jednak, że nie powinieneś:

  • skonfiguruj aspekty projektu, a nie koduj je na stałe w swoim rozwiązaniu. Albo przez parametry przekazane w czasie wykonywania, albo przez zewnętrzną konfigurację odczytaną przy uruchomieniu (lub po HUP'ingu).
  • zasznuruj swój kod magicznymi liczbami,
  • unikaj sprawdzania, czy istnieje już coś, co można ponownie wykorzystać, być może po dostosowaniu istniejącego rozwiązania, aby zapewnić podejście odpowiednie dla istniejącej sytuacji, a także dla nowych wymagań.

Głównym problemem związanym z projektowaniem „możliwych przyszłości” jest to, że zawsze zgadujesz. Być może podejmowanie wykształconych domysłów, ale „kiedy przychodzi do odpychania” to wciąż tylko seria domysłów.

Robiąc to, masz również bardzo realną możliwość ściśnięcia rozwiązania, aby dopasować go do ogólnego przypadku (przypadków), zamiast rozwiązać konkretny problem, o którym mowa w Twoich znanych wymaganiach.

Co to mówi „Gdy wszystko, co masz, to młotek, wszystko zaczyna wyglądać jak gwóźdź”.

Chciałbym mieć funta za każdym razem, gdy słyszę, jak ktoś mówi: „Ale jest to rozwiązanie, które można lepiej dostosować do tych ogólnych przypadków, które możemy zobaczyć w przyszłości”.

Rob Wells
źródło