Projektowanie oprogramowania: Zbuduj to szybko czy dobrze?

38

Budując nietrywialną aplikację, najlepiej skupić się na szybkim działaniu i na skrótach w kodzie, takich jak mieszanie logiki modelu z widokami, łamanie enkapsulacji - typowy zapach kodu? Lub, czy lepiej jest poświęcić czas na zbudowanie większej architektury, zbudować ją poprawnie, ale ryzykując, że cały ten dodatkowy kod może nie zostać użyty, ponieważ projekt jest dość płynny i być może będziesz musiał go wyrzucić, jeśli informacja zwrotna spowoduje iść w innym kierunku?

Dla kontekstu buduję aplikację komputerową. Jestem jedynym programistą i pracuję na pół etatu, ponieważ mam pracę na co dzień. Teraz w pracy staram się robić rzeczy we właściwy sposób, zgodnie z harmonogramem. Ale w przypadku tego projektu, który, jak się spodziewam, zmieni się w miarę uzyskiwania informacji zwrotnych od ludzi, nie jestem pewien, czy jest to właściwe podejście. W tym tygodniu spędziłem kilka godzin, przygotowując podręcznik Model View Controller, aby przekazać zmiany w modelu widokowi. Ogólnie jest to świetne, ale nie jestem pewien, czy potrzebuję wielu widoków do wyświetlania danych i wiem, że mogłem wyświetlać rzeczy szybciej bez dodatkowej architektury. Wydaje mi się, że może poświęcić 10–15 godzin tygodniowo na projekt, że zbudowanie czegoś, co będę w stanie wykonać, zajmie wieki, jeśli będę postępować zgodnie z dobrymi praktykami oprogramowania. Wiem, że moi użytkownicy wygrali ” troszczy się o to, że użyłem MVC wewnętrznie, po prostu chcą czegoś, co rozwiąże ich problem. Ale byłem również w sytuacji, w której zaciągnąłeś tak wiele długów technicznych z powodu skrótów, że kod jest po prostu niezwykle trudny w utrzymaniu i dodaje nowe funkcje. Chciałbym usłyszeć, jak inni ludzie podchodzą do tego rodzaju problemów.

Pedro Estrada
źródło
10
„Nigdy nie ma czasu, aby zrobić to dobrze, ale zawsze jest czas, aby to zrobić”.
Scott Whitlock
1
Wiesz, jak mówią doradcy finansowi, po prostu nie popadaj w długi? Nie popadaj też w długi techniczne :)
Nicole
3
obowiązkowe odniesienie xkcd: xkcd.com/844
user281377
@ammoQ pobił mnie do tego.
1
Steven: Z mojego doświadczenia wynika, że ​​założenie to obowiązuje, podczas gdy przyszłe wymagania mieszczą się w oczekiwanym (i przygotowanym koncepcyjnie) zakresie; ale czasami nowy wymóg wymaga „upiornej interakcji na odległość”, która jest jeszcze trudniejsza do zaimplementowania we właściwym projekcie, ponieważ wszystkie te starannie odseparowane klasy, warstwy itp. nagle muszą się komunikować w sposób, na jaki projekt nie był przygotowany .
user281377

Odpowiedzi:

48

Zbuduj to dobrze .

Budowanie go „szybko” jest logicznym błędem, jeśli spojrzy się na duży obraz. Zapobiegnie to poprawnemu zbudowaniu, a w końcu wpadniesz w błędy i fundamentalne wady architektury, które uniemożliwiają refaktoryzację, a nawet uniemożliwiają dodanie nowych funkcji.

Właściwe zbudowanie go jest wręcz przeciwne. Na początku może być wolniej, ale w końcu zdasz sobie sprawę ze wzrostu wydajności po poświęceniu czasu na dokonanie właściwych wyborów z góry. Ponadto będzie można łatwiej dostosować się do przyszłych wymagań (w razie potrzeby refaktoryzować) i uzyskać lepszy produkt końcowy, przynajmniej z powodu mniejszej liczby błędów.

Innymi słowy (chyba że jest to umowa jednorazowa), zbuduj ją szybko = zbuduj powoli, dobrze zbuduj = zbuduj szybko .


Jest także coś ważnego do zrozumienia w „dobrym budowaniu” i projektowaniu architektury. Zapytałeś...

... ale ryzykujesz, że cały ten dodatkowy kod może nie zostać użyty, ponieważ twój projekt jest dość płynny i być może będziesz musiał go wyrzucić, jeśli informacja zwrotna spowoduje, że pójdziesz w innym kierunku?

To nie jest tak naprawdę prawdziwe ryzyko związane ze „spędzaniem czasu na architekturze”. Projektowanie architektury powinno być organiczne . Nie trać czasu na projektowanie architektury dla dowolnej części, dopóki nie będzie to uzasadnione. Architektura powinna ewoluować wyłącznie z zaobserwowanych i potwierdzonych wzorców w twoim projekcie.

Prawo Johna Galla z Systemantyki :

Złożony system zaprojektowany od podstaw nigdy nie działa i nie można go załatać, aby działał. Musisz zacząć od nowa, zaczynając od działającego prostego systemu.

NickC
źródło
9
Nie mogę głosować wystarczająco. Kolejny dobry cytat pochodzi od wujka Boba „Jedynym sposobem na szybkie jest pójście dobrze”
CaffGeek
1
+1, ponieważ gdy zrobisz to dobrze, możesz ponownie użyć tego kodu i ponownie podejść do następnego projektu, a będzie jeszcze szybciej. Płucz i powtarzaj, aż będzie to druga natura.
Gary Rowe
4
Na cześć mojego taty: „Jeśli za pierwszym razem połapiesz go w dupę, będziesz miał podwójną ilość pracy, kiedy wrócisz, aby to naprawić”.
Pan Ant
Hej ... wzór sprawił, że pomyślałem: zbuduj dobrze = zbuduj szybko = zbuduj powoli. Wydaje mi się, że ostatni „buduj to szybko” powinien być budowany za mniej, co dotyczy długu technicznego. Ponieważ potrzeba mniej pracy, aby zbudować dobrze wykonany system.
Spoike 22.01.11
@Spoike Zgadzam się, ale pomysł jest taki: „zbuduj to dobrze = zbuduj to szybko później ”. Tak wielu menedżerów nie chce zrezygnować z prędkości na kilka miesięcy, co faktycznie zwiększy prędkość później.
Nicole,
17

Szybko więc dobrze

To z mojego osobistego doświadczenia, że ​​wypróbowałem wiele różnych metod.

Problem z szybkim działaniem (i zwalnianiem) polega zazwyczaj na tym, że wprowadzasz funkcję po funkcji do swojej aplikacji, a ponieważ została ona wydana, bardzo trudno jest wprowadzić fundamentalne zmiany w programie. Na dłuższą metę płacisz wysoką cenę za nic, co nie ma solidnej architektury, to jak budowanie rozpaczliwego ruchu na ruchomych piaskach.

Program robiąc to dobrze polega na tym, że zmarnujesz dużo czasu i kodu. To jak budowanie rezydencji bez żadnych planów. Pisanie aplikacji jest procesem uczenia się i prawie (z mojego doświadczenia) niemożliwym jest zaprojektowanie z góry. Oznacza to, że dokonasz dużo refaktoryzacji, a jeśli będziesz pisać wszystko „dobrze” przez cały czas, w końcu wyrzucisz dużo kodu.

Dlatego szybko, więc dobrze!

Najważniejsze, kiedy zaczynasz, jest po prostu zapisanie wszystkiego w kodzie, aby można było wykonać wszystkie funkcje i zobaczyć, jaką architekturę musisz obsługiwać. Kolejną dobrą rzeczą w tej metodologii jest to, że będę cię motywować, ponieważ szybko coś uruchomisz. Ważne jest również, aby zaimplementować niektóre funkcje „na krawędzi”, ponieważ będzie to miało wpływ na ogólną architekturę. Na tym etapie nie zawracaj sobie głowy pisaniem testów jednostkowych ani pracą nad szczegółami. Jeśli uważasz, że będziesz musiał w przyszłości obsługiwać wielojęzyczność, architekturę wtyczek, co nie, zaimplementuj ją, ale szybko i brudnie. Wykonaj trochę refaktoryzacji, aby aplikacja była łatwa do zarządzania, ale nic nadmiernego.

Gdy poczujesz, że masz działający „prototyp”, czas rozpocząć refaktoryzację. Zasadniczo chcesz powtórzyć aplikację tak, jakbyś to zrobił, gdybyś zaczął od zera, wiedząc wszystko, co teraz wiesz. Ważne jest, aby uzyskać poprawną architekturę , a nie ponownie wdrożyć wszystkie funkcje wykonane w fazie pierwszej, ale powinieneś mieć architekturę na miejscu, aby ją później obsługiwać.

W ten sposób uzyskasz aplikację o architekturze dźwięku tak wydajnie, jak to możliwe, i tak z mojego doświadczenia :)

konrad
źródło
2
+1 Tak, dodałbym - stosując podejście iteracyjne ..
pmod
Zgadzam się z tą odpowiedzią. I zgadzam się z pmod.
Kim Jong Woo
Szybkość iteracji bije jakości iteracji - Zgodnie Stack Exchange Network samych - z przykładami dobrych - codinghorror.com/blog/2010/09/go-that-way-really-fast.html
jasonk
10

Zbuduj to

Szybko, jeśli czas na sprzedaż jest ważniejszy niż jakość

Cóż, jeśli jakość jest ważniejsza niż czas wprowadzania na rynek

użytkownik2567
źródło
8

Szybkie budowanie przyniesie Ci krótkoterminowe korzyści i długoterminowe straty.

Dobre budowanie przyniesie krótkoterminowe straty, ale długoterminowe korzyści.

Budowanie go dobrze wymaga cierpliwości i mądrości, ale zostaniesz nagrodzony.

Szybkie budowanie jest dobre tylko do szybkiego prototypowania i wyrzucania rzeczy. Cele długoterminowe można osiągnąć tylko od samego początku.

użytkownik8685
źródło
5

W przypadku projektów, które planujesz rozpowszechniać do użytku innych, zawsze popełniam błąd po stronie pracy z góry. Dobrze przemyślana architektura jest łatwiejsza w razie potrzeby. Skracanie jest tylko modelem kumulacji długu technicznego.

Czasami może być frustrująco powolny. Rzeczy, które warto robić, warto robić dobrze.

Jeff
źródło
1
Wystarczy zakwalifikować to „dobrze przemyślane” stwierdzenie: nie oznacza to myślenia o wszystkim z góry (nie da się tego zrobić), ale po prostu poświęcenie czasu na przemyślenie, jak zintegrować funkcję, a nie rzucenie jej gdzieś i załatwienie sprawy .
Matthieu M.
5

Dobre budowanie = szybkie budowanie

Skróty mają tendencję do obracania się i gryzienia cię nawet szybciej, niż myślisz. Czasami nawet przed lunchem.

O twoim kontekście; nie streszczaj natychmiast. Trzymaj się YAGNI i usuń duplikację. Zaimplementuj ten wzorzec oparty na Widoku, gdy faktycznie masz drugi widok, nie dlatego, że uważasz, że możesz go mieć w przyszłości. Kiedy pojawia się ten drugi Widok, tworzona abstrakcja jest zwykle znacznie lepsza niż ta, którą stworzyłbyś wokół tego pierwszego pojedynczego wystąpienia.

Joppe
źródło
3

Cóż, jeśli już wiesz, co robisz, szybko, jeśli nie

Jestem naukowcem i piszę dużo kodu eksploracyjnego, zanim będę miał jakąkolwiek wiedzę na temat tego, jak duży jest obraz i jak rozwinie się projekt. W takich przypadkach trudno nawet zobaczyć, jak należy zdefiniować „dobrze”. Ponadto zwykle trudno jest zobaczyć wszystkie małe szczegóły i sposoby, w jakie rzeczy mogą zostać rozszerzone z góry. Dlatego obowiązuje stare przysłowie:

  1. Niech to zadziała.
  2. Zrób to dobrze. Zrobienie tego na drugim miejscu ma tę zaletę, że możesz lepiej zdefiniować „właściwe”, gdy tylko doświadczysz, że działa.
dsimcha
źródło
2

Zbuduj to dobrze ... zawsze, ale daj złudzenie szybkiego działania

ale aby był szybki, po prostu zmniejsz go. Zbuduj mały podzbiór całości, który jest wystarczająco znaczący, aby uzyskać informację zwrotną. Stopniowe dodawanie do niego w stałym tempie przyniesie wiele takich samych korzyści szybkiego budowania bez sprzedawania swojej duszy reakcji łańcuchowej nieprzespanych nocy grających w cholerę.

Newtopian
źródło
+1, buduj tylko to, co jest naprawdę potrzebne.
Nicole
1

Myślę, że zawsze powinien być „dobrze zbudowany”. Jeśli czas wprowadzenia produktu na rynek stanowi poważny problem, zastosuj proces stopniowego rozwoju. W najgorszym przypadku masz produkt z mniejszą liczbą funkcji, ale przynajmniej masz produkt wysokiej jakości do wysyłki, który można rozszerzyć w przyszłych wydaniach funkcji.

Pemda
źródło
1

Saldo

Nie jest praktyczne dopracowanie kodu do perfekcji lub zmiksowanie jakiegoś kodu w mgnieniu oka, prawda? To naprawdę chodzi o osiągnięcie właściwej równowagi. Moim zdaniem liczy się to, co robisz, kiedy.

Myślę, że najważniejsze jest tutaj absolutne zapewnienie, że rdzeń aplikacji, podstawowa struktura, zostanie zbudowany naprawdę dobrze. Hermetyczny. Gdy zostanie to osiągnięte, w zależności od ograniczeń czasowych, jeśli masz mało czasu, możesz zebrać trochę kodu i ponownie go rozłożyć na później, i możesz sobie pozwolić na ten luksus, ponieważ zadbałbyś o fundację tak, i nie zaszkodzi ponowna faktoryzacja kodu.

Shreyas Satish
źródło
poprawny. Zbuduj go tak dobrze, jak to możliwe, biorąc pod uwagę dozwolony czas.
jwenting
1

Zrób najprostszą rzecz, która może działać. W twoim szczególnym przypadku twój program nie stanie się zbyt duży, ponieważ będziesz jedyną osobą pracującą nad nim w niepełnym wymiarze godzin. Nie opowiadam się za złymi manierami, takimi jak nadużywanie goto, nieokreślone nazwy zmiennych itp., Ale nie powinieneś robić tego bardziej złożonego, niż być musi. Może MVC to po prostu przesada dla twojego konkretnego projektu.

użytkownik 281377
źródło
0

co, jak się spodziewam, zmieni się, gdy otrzymam informację zwrotną od ludzi

Sam to powiedziałeś najlepiej:

Ale byłem również w sytuacji, w której zaciągnąłeś tak wiele długów technicznych z powodu skrótów, że kod jest po prostu niezwykle trudny w utrzymaniu i dodaje nowe funkcje.

Jeśli brakuje Ci czasu, nie bój się prosić o więcej czasu na ukończenie projektu od pracodawcy, korzystając z tego samego rozumowania. Jestem pewien, że ci to udzielą. Powiedziawszy to, rozumiem, jak frustrujące może być czasami ciężko pracować nad czymś i nie być w stanie pochwalić się zbyt dużym rezultatem. Ale nie martw się, dostaniesz się tam, a zbudowanie go dobrze będzie na pewno tego warte.

Rob S.
źródło
0

Zazwyczaj lubię dobrze budować strukturę i oszczędzać czas, nie martwiąc się o konkretne szczegóły implementacji. Tak jak mówisz, i tak się zmienią. Ideą budowy dobrze wykonanej konstrukcji jest to, że zmiany mogą nastąpić bardzo szybko, po zbudowaniu bazy. Staram się skupiać na byciu tak ogólnym, jak to możliwe na moich zajęciach, i aby można je było powtarzać, gdy to możliwe. Zwykle daję użytkownikowi dobrze zbudowaną aplikację, która spełnia tylko najbardziej podstawowe wymagania dotyczące użyteczności. Użytkownicy otrzymują różnego rodzaju pomysły, gdy narzędzie jest w zasięgu ręki, więc nie ma sensu myśleć daleko w przyszłość.

Kratz
źródło
0

Zbuduj to dobrze . Jeśli nie masz czasu, zmniejsz zestaw funkcji.

Zaprojektuj go tak uniwersalnie, jak to tylko możliwe. Np. Zaprojektuj architekturę wtyczki, nawet jeśli wiesz, tylko jedna wtyczka zostanie użyta za pierwszym razem. Używaj uniwersalnych schematów konfiguracji (konfiguracja rozszerzalna, język organizacyjny), nawet na początku jest tylko jeden parametr. To bardzo dobra inwestycja , którą możesz zainwestować dopiero na początku projektu.

ern0
źródło
0

czy najlepiej jest skoncentrować się na szybkim działaniu i wprowadzaniu skrótów w kodzie, takich jak mieszanie logiki modelu z widokami, łamanie enkapsulacji - typowy zapach kodu? A może lepiej jest poświęcić trochę czasu na zbudowanie większej architektury

W moich uszach, jak to tam umieściłeś, wymieniasz dwie skrajności. Pierwszy wybór, przełamanie enkapsulacji, umieszczenie logiki modelu w widokach, to po prostu kiepskie leniwe programowanie. IMHO, rozwiązanie tych problemów to nie to samo, co zwiększenie architektury. Być może, chyba że mówisz o tym, że kod interfejsu użytkownika wykonuje instrukcje SQL. Ale wtedy nie powiedziałbym, że buduj więcej architektury, wtedy powiedziałbym, że masz kompletny brak projektu i architektury i powinieneś je zdobyć.

Jeśli chodzi o architekturę, wybrałbym ten najprostszy, który rozwiązuje teraz twój problem, a następnie rozwija się w miarę pojawiania się problemów.

Np. Czy potrzebujesz teraz funkcjonalności, aby zwrócić dane z jednej tabeli bazy danych, nie martwiłbym się takimi problemami, jak ładowanie danych z powiązanych tabel, nawet jeśli wiedziałbym, że problem w końcu się pojawi. Zaczynam się o to martwić, kiedy mogę wdrożyć tę funkcjonalność.

Tak więc w przypadku własnych projektów deweloperskich wybrałbym następujące podejście: Zbuduj najprostsze możliwe rozwiązanie, które rozwiąże problem, nad którym teraz pracuję, ale zbuduj je dobrze. Następnie przefakturowałbym rozwiązanie, ponieważ potrzebna jest większa złożoność. Postępowanie zgodnie z praktykami TDD sprawia, że ​​refaktoryzacja jest bezpieczna, a także pomaga uniknąć zapachów kodu (trudno jest stworzyć dobre testy jednostkowe, jeśli łamie się enkapsulację).

Tak zresztą jest to również podejście, które podchodzę do pracy zawodowej. ;)

Pete
źródło
0

Radziłbym najpierw, abyś wstał z oprogramowaniem, obejmował każdy aspekt i najpierw postawił oprogramowanie, a następnie stopniowo udekorował i poprawił jego działanie

Pir Abdul
źródło
-1

Zwykle chcesz znaleźć się pośrodku tych dwóch krawędzi:

Zbuduj to dobrze = krytyczne dla życia oprogramowanie czasu rzeczywistego, od którego zależy życie ludzi. tj. sterowanie oprogramowaniem: reaktory jądrowe, maszyna do dializy, maszyny do rezonansu magnetycznego itp.

Zbuduj to szybko = bezużyteczne oprogramowanie, którego nikt tak naprawdę nie używa.

vz0
źródło
ha! zbudować bezużyteczne oprogramowanie ...
pmod
Czy jest jakiś powód negatywnego głosowania?
vz0