Ile szczegółów należy wprowadzić w pierwszej iteracji projektu?

15

Właśnie rozpocząłem nowy osobisty projekt (Python) i piszę, co stanowi „wstępny szkic” programu, minimum wymagane do zrobienia tego, co chcę. Nie wprowadzam jeszcze obszernej obsługi błędów / wyjątków ani estetycznych elementów interfejsu użytkownika (nawet w przypadkach, gdy wiem, że te rzeczy ostatecznie będą potrzebne), a dokumentacja jest wystarczająca, aby pomóc w przyszłości zobaczyć, co robię.

Czy rozpoczęcie tak surowego działania jest niezgodne z jakimikolwiek ustalonymi zasadami projektowania / zarządzania projektem? Jestem naukowcem, a nie programistą, więc nie jestem na bieżąco z tymi sprawami. Zatem główne pytanie brzmi: czy istnieje konsensus co do tego, gdzie należy dążyć do upadku między dwoma skrajnościami:

  1. Napisz dokładny, wysokiej jakości kod od samego początku, z obsługą wszystkich wyjątków i tak, abyś wiedział, że ostatecznie będziesz potrzebować.

  2. Napisz od początku minimalnie działający wstępny szkic i wejdź, aby wypełnić wszystkie szczegóły później.

Powiązane pytanie: kiedy można poświęcić „czystość” projektu, aby zrealizować projekt?

neuronet
źródło
1
Uwaga dla potencjalnych odpowiedzi: PO dokładnie pyta, jak zrównoważyć jakość kodu z szybkością programowania w (prawdopodobnie) wczesnych cyklach iteracji projektu. Pytanie nie dotyczy tego, czy produkt końcowy powinien być wysokiej jakości (obsługa błędów robus itp.), Ale kiedy prototyp powinien rozpocząć dołączanie lub konwersję do kodu wysokiej jakości.
Lilienthal,

Odpowiedzi:

10

Nie ma jednej odpowiedzi, ponieważ zależy to całkowicie od projektu. Musimy tutaj pomyśleć o dwóch rzeczach. Jaki jest twój ostateczny cel? Jak się tam dostać?

Wynik końcowy

Czy piszesz oprogramowanie sterujące Mars Orbiter? W takim razie lepiej upewnij się, że piszesz najbardziej niezawodny kod. Lepiej sprawdź, czy każdy wyjątek jest obsługiwany w rozsądnej sprawie.

Czy piszesz program, który tylko Ty będziesz uruchamiał i co jakiś czas będziesz uruchamiał ręcznie? Więc nie zawracaj sobie głowy wyjątkami. Nie przejmuj się ciężką architekturą. Spraw, by działał do punktu, w którym działa dla Ciebie.

Jak się tam dostać?

Robisz ciężki rozwój wodospadów, gdzie spędzasz dużo czasu, zastanawiając się, co jest potrzebne, a potem wyruszasz na miesiące, rozwijając się? Jeśli tak, to dość wcześnie chcesz osiągnąć wspomnianą wyżej jakość docelową. Zaplanuj na początku całą infrastrukturę sprawdzania błędów.

Czy robisz intensywny, zwinny rozwój, w którym gromadzisz coś przez tydzień lub dwa, co zostanie następnie pokazane interesariuszom, którzy mogą poprosić o radykalne zmiany, i gdzie spodziewasz się, że będziesz w stanie iterować przez wiele 1-2 tygodniowych sprintów dopóki nie trafisz w cel? W takim razie lepiej jest mieć coś działającego, ale szybko kruche i dodając tylko pasy i szelki, gdy wymagania produktu się zestalą.

Jeśli masz kontrolę nad wodospadem lub zwinną decyzją (która w rzeczywistości jest kontinuum, a nie wyborem binarnym), podejmij tę decyzję na podstawie oczekiwanej zmiany. Jeśli jesteś pewien, że wiesz dokładnie, jak będzie wyglądał efekt końcowy, to wodospad jest najlepszym wyborem. Jeśli masz tylko niejasne pojęcie o tym, czego potrzebujesz, zwinny jest najlepszym wyborem. (Zwinność jest obecnie bardziej popularna nie dlatego, że jest z natury lepsza, ale dlatego, że druga sytuacja jest znacznie częstsza).

Teraz znajdź własną odpowiedź

Dla większości odpowiedź leży gdzieś pośrodku. Odpowiedz na oba pytania dotyczące swojego projektu, a powinien on poprowadzić Cię w podstawowym kierunku.

Mogę to powiedzieć dla siebie, jeśli często piszę jednorazowe skrypty, które są absurdalnie zaprojektowane i nie mają błędów sprawdzania czegokolwiek. Zajmuję się także kodem produkcyjnym, w którym dużą uwagę zwraca obsługa błędów i architektura. Wszystko zależy od tego, co robisz.

Ostatnie ostrzeżenie: jeśli zdecydujesz, że robisz jednorazowe skrypty, które można wykonać szybko i brudnie, upewnij się. Niestety często zdarza się, że szybkie i brudne skrypty, które robią coś interesującego, stają się szeroko stosowane, gdy inni je zauważą. Upewnij się, że gdy tak się stanie, poświęcony zostanie czas na utwardzenie.

Gort the Robot
źródło
Bardzo pomocna informacja! Mój jest niewielkim projektem, który nie jest krytyczny dla środków do życia, i chcę wkrótce opinii na temat minimalnego modelu roboczego, aby zrozumieć, co ludzie myślą o ogólnej strukturze. Myślę więc, że wstępny szkic jest w porządku, ale twoja ostatnia uwaga jest doskonała: kolejną obawą jest to, że kończę szkic, ale nigdy nie wprowadzaj ulepszeń, które musiałbym wprowadzić, aby doprowadzić go do poziomu dobrego programowania (w przeciwieństwie do „go” ledwo działa „programowanie”.
neuronet
1
@neuronet: Czasami wystarczająca jest niezawodność „to ledwo działa”. Jednym ze sposobów myślenia o tym jest porównanie frustracji wynikającej z pracy z oprogramowaniem z wymaganą niezawodnością. Im bardziej frustrujące są problemy z oprogramowaniem, tym ważniejsze jest ich rozwiązanie.
Bart van Ingen Schenau,
11

Wszystkie koncepcje i wzorce projektowania i kodowania oprogramowania powstają w odpowiedzi na jakiś problem. Wzór lub koncepcja jest rozwiązaniem tego problemu. Z czasem niektóre wzorce stają się „dobrze znane” jako preferowane rozwiązania, ponieważ rozwiązują problem w sposób, który spełnia określone wymagania dotyczące spójności, znajomości, wydajności, łatwości konserwacji i tak dalej.

Wynika z tego, że jeśli problem, który ma rozwiązać wzór oprogramowania, nie występuje w twoim oprogramowaniu, nie potrzebujesz wzoru. Ponadto wszelkie dyskusje na temat wzorów, których może potrzebować oprogramowanie, muszą również obejmować szczegółowe dyskusje na temat proponowanego oprogramowania: co to ma zrobić? Jaki problem rozwiązuje? Ilu będzie użytkowników? Czy użytkownicy będą w jakiś sposób udostępniać dane? I tak dalej.

Problem, który mają rozwiązać wyjątki, polega na tym, że dzieje się coś, czego kod nie może zrobić. Przykładem może być operacja Plik / Otwórz, w której podano nazwę pliku, która nie istnieje na nośniku pamięci. Wyjątki dają kodowi sposób powiedzenia dzwoniącemu: „Coś się stało, co uniemożliwia mi kontynuowanie, i nic nie mogę na to poradzić, więc się poddaję”. Jeśli nie masz żadnych miejsc w kodzie, w których istnieją takie warunki, nie potrzebujesz wyjątków. Możesz też po prostu zwrócić kod błędu i całkowicie uniknąć wyjątku.

W miarę zdobywania doświadczenia poznasz wzorce oprogramowania i kiedy ich użycie jest właściwe. Dowiesz się również, ile potrzebujesz z góry projektu; znowu, to całkowicie zależy od pisanej aplikacji. Innymi słowy, małe narzędzia pisane są w zasadniczo odmienny sposób niż duże aplikacje korporacyjne.

Robert Harvey
źródło
Zalety: w swoim pytaniu wyjaśniłem, że odkładam rzeczy, które wiem (na podstawie innych projektów), których ostatecznie potrzebuję w gotowym projekcie.
neuronet
Mam nadzieję, że wyjaśniłem, że nawet jeśli znasz te rzeczy, jeśli ich nie potrzebujesz, to nie potrzebujesz ich.
Robert Harvey
4

Istnieje bardzo proste i praktyczne podejście do tego, które działa w szerokim zakresie małych i średnich projektów. Mimo że prawdopodobnie nie zadziała to dobrze dla Odkrywców Marsa.

Najpierw ustal, co chcesz zrobić, i zanotuj poszczególne funkcje. Może to być tak wyrafinowane, jak cała plansza użytkownika lub tak proste, jak kilka kul wypisanych na kawałku papieru przed sobą. Ale ważne jest, abyś wiedział, co chcesz zrobić.

Na tej podstawie opracuj ogólną strukturę systemu. Ponownie, bardzo często jest to tylko szybki rysunek różnych klas / modułów i ich wzajemnych relacji, ale może być tak złożony jak cały dokument. Ważne jest to, że masz jakieś pojęcie o tym , jak zamierzasz wdrożyć system. Ale prawdopodobnie będzie to dopracowane w miarę pracy nad nim, więc nie próbuj wchodzić w skomplikowane i szczegółowe.

Ze wszystkich tych funkcji ustal, jakie są kluczowe rzeczy, które program musi zrobić - podstawowe funkcje.

Następnie wdrażaj je jeden po drugim. Teraz najważniejsze jest to, aby upewnić się, że po zaimplementowaniu funkcji jest to zrobione i działa w pełni - idealnie towarzyszy temu test jednostkowy, który upewnia się, że nadal działa. Zazwyczaj zakładam, że będę tak zajęty, że nigdy nie będę miał czasu, aby wrócić do tej funkcji i naprawić ją.

Po zaimplementowaniu podstawowych funkcji zazwyczaj staram się, aby system był używany jak najbliżej środowiska produkcyjnego. Daje to a) wszelkie błędy, które mogły zostać pominięte wcześniej oraz b) masz dobre pojęcie o priorytecie następnych funkcji.

Następnie możesz nadal wdrażać pozostałe funkcje w razie potrzeby.

Jakość kodu a funkcje

Mając powyższe na uwadze, staram się poświęcać cechy nad jakością kodu, jeśli muszę dotrzymać terminu. Po prostu dlatego, że przynajmniej w mojej branży, kiedy kończę coś, moje kierownictwo zakłada, że ​​jest to zrobione. I że mogą mi dać kolejne zadanie. Po tym fakcie nie mam dużo czasu na poprawianie kodu.

A co z obsługą wyjątków?

Jeśli nie chcesz tego wdrażać poza batem, możesz po prostu wymienić to jako kolejną funkcję na liście. A kiedy do tego dojdziesz, możesz to zaimplementować. Ale najprawdopodobniej w twoim przypadku jest prawdopodobnie wiele innych rzeczy, które są ważniejsze w pierwszej kolejności.

Istnieją jednak minimalne wymagania dotyczące wyjątków: Upewnij się, że użytkownik zostanie powiadomiony, jeśli coś pójdzie nie tak - bez względu na to, jak brzydka może być jakość wydruku. Nie połykaj gdzieś wyjątków.

ced-b
źródło
1
„Zazwyczaj zakładam, że będę tak zajęty, że nigdy nie będę miał czasu, aby wrócić do tej funkcji i ją naprawić”. to zmartwienie, o którym powinienem wspomnieć. Cieszę się, że o tym wspomniałeś i za pomocny post.
neuronet