Czy rozwiązanie powinno być jak najbardziej ogólne lub jak najbardziej szczegółowe?

LoveProgramming 11/30/2017. 14 answers, 14.835 views
programming-practices api-design requirements

Powiedzmy, że mam podmiot, który ma atrybut "typ". Może być ponad 20 możliwych typów.

Teraz jestem poproszony o zaimplementowanie czegoś, co pozwoliłoby na zmianę typu z A-> B, który jest jedynym przypadkiem użycia.

Więc czy powinienem zaimplementować coś, co pozwala na dowolne zmiany typu, o ile są one poprawnymi typami? Czy powinienem TYLKO zezwolić na zmianę z A-> B na wymaganie i odrzucić wszelkie inne zmiany typu, takie jak B-> A lub A-> C?

Widzę zalety i wady z obu stron, w przypadku których ogólne rozwiązanie oznaczałoby mniej pracy, gdyby podobny wymóg pojawił się w przyszłości, ale oznaczałoby to również większą szansę na błąd (chociaż w 100% kontrolujemy dzwoniącego w tym punkt).
Konkretne rozwiązanie jest mniej podatne na błędy, ale wymaga więcej pracy w przyszłości, jeśli pojawi się podobny wymóg.

Wciąż słyszę, że dobry programista powinien starać się przewidzieć zmianę i zaprojektować system, aby był łatwy do rozbudowania w przyszłości, co brzmi jak ogólne rozwiązanie jest drogą do zrobienia?

Edit:

Dodanie większej ilości szczegółów do mojego niezbyt szczegółowego przykładu: "Ogólne" rozwiązanie w tym przypadku wymaga mniej pracy niż "konkretne" rozwiązanie, ponieważ konkretne rozwiązanie wymaga sprawdzenia poprawności na starym typie i nowym typie, podczas gdy ogólne rozwiązanie wystarczy zweryfikować nowy typ.

5 Comments
95 T. Sar 11/30/2017
To interesujące pytanie. Rozmawiałem o czymś takim z moimi grampami (bardzo, very stary programator czasowy), a jego odpowiedź była czymś w rodzaju "najbardziej ogólnej rzeczy, która rozwiązuje twój konkretny problem", która sprowadza się do wyobraźni " To zależy". Powszechne oświadczenia w zakresie tworzenia oprogramowania rzadko działają - rzeczy powinny być podejmowane zawsze w każdym indywidualnym przypadku.
2 Christophe 11/30/2017
@ T.Sar dodaj to jako odpowiedź, a ja porozmawiam :-)
4 RibaldEddie 11/30/2017
Jakie jest "ogólne rozwiązanie" w twoim widoku? Proszę również wyjaśnić, co rozumiecie przez "przypadek użycia tylko". Czy masz na myśli, że dozwolone jest tylko przejście z A-> B lub tylko to przejście jest określone i nie byłoby warunek błędu przejścia z dowolnego innego stanu do innego stanu. Jako programista musisz poprosić autora o przypadek użycia w celu wyjaśnienia. Jeśli żadne inne przejście nie jest dozwolone, a kod na to pozwala, niezależnie od tego, kto kontroluje dzwoniącego, Twój kod nie spełnia wymagań.
5 sdenham 12/01/2017
Zasada, że ​​jeśli X jest dobrym pomysłem, to tylko X cały czas musi być optymalny, wydaje się mieć szczególny apel do programistów (lub przynajmniej do grupy wokalnej między nimi), ale rozważ to: zasady programowania kciuka są jak przysłowia, ponieważ często można znaleźć parę o przeciwnych implikacjach. Jest to znak, że powinieneś użyć swojego osądu (jak zalecają tu odpowiedzi) i uważaj na dogmat.
2 John Bode 12/01/2017
Przedwczesna generalizacja może powodować tyle zgagi co przedwczesna optymalizacja - kończy się pisanie wielu kodów, które mogą nigdy nie zostać wykorzystane. Najpierw rozwiązano konkretny problem, a następnie uogólniano, gdy zajdzie taka potrzeba.

14 Answers


Daniel Pryden 12/01/2017.

Moja zasada:

  1. gdy pierwszy raz napotkasz problem, rozwiąż tylko konkretny problem (to zasada YAGNI )
  2. za drugim razem, gdy napotkasz ten sam problem, rozważ uogólnienie pierwszego przypadku, jeśli to nie jest dużo pracy
  3. gdy masz trzy konkretne przypadki, w których będziesz mógł użyć uogólnionej wersji, powinieneś zacząć naprawdę planowanie uogólnionej wersji - do tej pory powinieneś zrozumieć problem wystarczająco dobrze, aby móc go uogólnić.

Oczywiście jest to wytyczna, a nie zasada, która jest twarda i szybka: prawdziwą odpowiedzią jest zastosowanie najlepszego osądu, na podstawie każdego przypadku.

5 comments
1 Bernhard 12/01/2017
Czy możesz wyjaśnić, czym jest YAGNI?
6 Angew 12/01/2017
@Bernhard Nie będziesz tego potrzebować . Bardzo przydatna zasada projektowania oprogramowania.
4 Joker_vD 12/01/2017
"W thing1, thing2 , pomyśl o użyciu tablicy thing1, thing2, thing3 , thing1, thing2, thing3 , prawie na pewno zamiast tego użyjesz tablicy thing[] ." jest podobną regułą do decydowania między wieloma zmiennymi lub pojedynczą tablicą.
13 Wayne Conrad 12/04/2017
Inny sposób na wyrażenie zasady nr 1: "Nie można uogólnić jednej rzeczy".
2 Daniel Pryden 12/05/2017
@SantiBailors: Jak mówi doktor Brown w swojej odpowiedzi, często ogromnie przeceniamy ilość zmarnowanego wysiłku, jaki możemy wydać, budując pierwszą, którą wyrzucimy. W The Mythical Man-Month Fred Brooks mówi: "Planuj wyrzucić jednego - tak czy inaczej". To powiedziawszy: jeśli natychmiast natkniesz się na więcej niż jedno użycie czegoś - na przykład dostarczając zestaw wymagań, w którym wyraźnie będziesz potrzebował rozwiązać ten sam problem więcej niż jeden raz - wtedy masz już więcej niż jeden przypadek do uogólnienia z, i to jest w porządku i nie jest w konflikcie z moją odpowiedzią.

Doc Brown 12/04/2017.

Konkretne rozwiązanie [...] wymaga więcej pracy w przyszłości, jeśli wymagany jest podobny wymóg

Słyszałem ten argument kilkadziesiąt razy i - ku mojemu doświadczeniu - to regularnie okazuje się błędem. Jeśli generalizujesz teraz lub później, gdy pojawi się drugie podobne wymaganie, praca będzie prawie taka sama. Więc nie ma sensu inwestować dodatkowego wysiłku w generalizację, kiedy nie wiesz, że ten wysiłek kiedykolwiek się opłaci.

(Oczywiście nie dotyczy to sytuacji, gdy bardziej ogólne rozwiązanie jest mniej skomplikowane i wymaga mniej wysiłku niż konkretny, ale z mojego doświadczenia wynika, że ​​są to rzadkie przypadki. Tego rodzaju scenariusz został następnie zmieniony na pytanie, a nie jest to jedna moja odpowiedź dotyczy).

Gdy pojawi się "drugi podobny przypadek", czas zacząć myśleć o generalizowaniu. Znacznie łatwiej będzie wtedy generalizować correctly , ponieważ to drugie wymaganie daje ci scenariusz, w którym możesz sprawdzić, czy zrobiłeś właściwe rzeczy. Próbując uogólnić tylko dla jednego przypadku, fotografujesz w ciemności. Istnieje duża szansa, że ​​nadmiernie scenizujesz pewne rzeczy, które nie muszą być uogólnione, i tracisz inne części, które powinny. A kiedy pojawia się druga sprawa i zdajesz sobie sprawę, że uogólniłeś złe rzeczy, to masz o much more work do zrobienia, aby to naprawić.

Polecam więc odłożyć wszelkie pokusy na robienie rzeczy "na wszelki wypadek". Takie podejście doprowadzi jedynie do zwiększenia nakładów pracy i konserwacji, gdy przegapisz okazję do generalizacji trzy, cztery lub więcej razy, a następnie będziesz mieć stos podobny do tego (tak podwójny) kod, aby go utrzymać.

5 comments
2 msb 11/30/2017
Dla mnie ta odpowiedź nie ma sensu w kontekście PO. Mówi, że poświęci mniej czasu na uogólnianie teraz i mniej czasu w przyszłości, chyba że w przyszłości będzie potrzeba konkretnej implementacji. Argumentujesz przeciwko "inwestowaniu dodatkowych wysiłków w generalizowanie", podczas gdy PO będzie inwestować dodatkowe wysiłki tylko wtedy, gdy don't uogólnią. (pomyśl) .... dziwne: $
2 Doc Brown 11/30/2017
@msb: ten kontekst został dodany po tym, jak napisałem swoją odpowiedź i jest sprzeczny z tym, co OP mówił wcześniej, szczególnie w części, którą zacytowałem. Zobacz moją edycję.
2 AndreKR 12/01/2017
Ponadto, uogólnione rozwiązanie będzie bardziej skomplikowane, więc do czasu, kiedy będziesz musiał go dostosować do drugiego przypadku, ponowne zrozumienie go zajmie znacznie więcej czasu.
4 user949300 12/01/2017
Doktorze, na bok, ale nigdy byście nie odgadli, że jesteście obcokrajowcami. Twoje odpowiedzi są zawsze dobrze napisane i dobrze przemyślane.
2 user949300 12/02/2017
Wyobrażę sobie twój akcent, kiedy będę czytał twoje przyszłe odpowiedzi. :-)

T. Sar 12/01/2017.

TL;DR: zależy to od tego, co próbujesz rozwiązać.

Miałem podobną rozmowę z moimi Gramps o tym, podczas gdy rozmawialiśmy o tym, jak Func i Action w C # są niesamowite. Mój Gramps jest bardzo starym programatorem czasowym, który jest w pobliżu kodów źródłowych od czasu uruchomienia oprogramowania na komputerach, które zajęły cały pokój.

Zmienił techników kilka razy w swoim życiu. Napisał kod w językach C, COBOL, Pascal, BASIC, Fortran, Smalltalk, Java i ostatecznie zaczął jako hobby. Nauczyłem się, jak programować z nim, siedząc na kolanach, gdy byłem tylko intrygującym, wyrywając moje pierwsze linie kodu na niebieskim edytorze SideKick firmy IBM. Kiedy miałem 20 lat, już spędziłem więcej czasu na kodowaniu niż na zabawie na zewnątrz.

To są niektóre z moich wspomnień, więc przepraszam, jeśli nie jestem dokładnie praktyczny, gdy je opowiadam. Trochę lubię te chwile.

Tak mi powiedział:


"Czy powinniśmy dążyć do uogólnienia problemu lub rozwiązać go w określonym zakresie, pytacie? Cóż, to jest ... pytanie."

Gramps zrobił krótką przerwę, zastanawiając się przez chwilę, poprawiając pozycję okularów na twarzy. Grał w grę match-3 na swoim komputerze, podczas słuchania płyty Deep Purple na swoim starym systemie dźwiękowym.

"Cóż, to zależy od tego, jaki problem próbujesz rozwiązać", powiedział mi. "Kuszące jest przekonanie, że istnieje jedno, święte rozwiązanie dla wszystkich wyborów projektowych, ale nie ma żadnego." Architektura oprogramowania jest jak ser, widzisz. "

"... Sery, Gramps?"

"Nie ma znaczenia, co myślisz o swoim ulubionym, zawsze znajdzie się ktoś, kto myśli, że jest śmierdzący".

Przez chwilę mrugałam zmieszana, ale zanim zdążyłam cokolwiek powiedzieć, kontynuował Gramps.

"Kiedy budujesz samochód, jak wybrać materiał na część?"

"Myślę, że to zależy od kosztów i tego, co należy zrobić, jak sądzę."

"To zależy od problemu, którego część próbuje rozwiązać, nie zrobisz opony ze stali lub przedniej szyby ze skóry, wybierz materiał, który najlepiej rozwiąże problem, który masz pod ręką. rozwiązanie generyczne? lub konkretny? do jakiego problemu, do jakiego przypadku? Czy powinienem zastosować pełne funkcjonalne podejście, aby dać maksymalną elastyczność kodowi, który będzie użyty tylko raz? Czy należy napisać bardzo specjalistyczny, kruchy kod do część twojego systemu, która zobaczy wiele zastosowań i ewentualnie wiele zmian? Wybory projektowe, takie jak te, które wybierzesz dla części samochodu lub kształt klocka Lego, który wybierzesz, aby zbudować mały dom Która cegła Lego jest najlepsza? "

Starszy programista sięgnął po mały model pociągu Lego, który ma na swoim stole, zanim przejdzie dalej.

"Możesz tylko odpowiedzieć, jeśli wiesz, for what potrzebujesz do tego klocka. Jak do cholery będziesz wiedzieć, czy konkretne rozwiązanie jest lepsze niż ogólne, czy odwrotnie, jeśli nie wiesz nawet, jaki masz problem próbujesz rozwiązać? Nie możesz zobaczyć przeszłości, której nie rozumiesz. "

".. Czy właśnie zacytowałeś The Matrix? "

"Co?"

"Nic, kontynuuj."

"Cóż, przypuśćmy, że próbujesz zbudować coś w National Invoice System. Wiesz, jak to piekielne API i jego trzydzieści tysięcy wierszy wygląda jak plik XML od środka. Jak mogłoby wyglądać" ogólne "rozwiązanie do tworzenia tego pliku? Plik jest pełen opcjonalnych parametrów, pełnych przypadków, które powinny być używane przez bardzo specyficzne gałęzie biznesu.W większości przypadków można je bezpiecznie zignorować.Nie musisz tworzyć ogólnego systemu faktur, jeśli jedyną rzeczą, którą " Będę sprzedawał buty, po prostu stwórz system sprzedaży butów i spraw, by był najlepszym systemem fakturowania do sprzedaży butów, teraz, gdybyś musiał stworzyć system fakturowania dla każdego typu klienta, w szerszym zastosowaniu - być odsprzedawanym jako niezależny, ogólny system sprzedaży, na przykład - teraz interesujące jest wdrożenie tych opcji, które są używane tylko w przypadku gazu, żywności lub alkoholu.Teraz są to możliwe przypadki użycia, zanim zostały tylko hipotetyczne Don't use sprawy, a ty nie chcesz wdrożyć Don't use Don't use przypadki. Don't use małego braciszka Don't need . "

Gramps odłożył pociąg z klocków lego na swoje miejsce i wrócił do swojej gry match-3.

"Aby móc wybrać ogólne lub konkretne rozwiązanie danego problemu, najpierw trzeba zrozumieć, do cholery, jaki jest ten problem, w przeciwnym razie po prostu zgadujesz, a zgadywanie jest zadaniem menedżerów, a nie programistów. wszystko w IT, to zależy. "


Tak, masz to. "To zależy". Jest to prawdopodobnie najpotężniejsza dwuliterowa ekspresja, gdy myślisz o projektowaniu oprogramowania.

5 comments
14 GoatInTheMachine 12/01/2017
Jestem pewna, że ​​w tej historii jest coś pożytecznego, ale było to zbyt bolesne, by ją przeczytać, przepraszam
28 GoatInTheMachine 12/01/2017
Twój pierwszy post był krótką, zabawną anegdotą - i oczywiście jest to kwestia opinii - ale jeśli really lubię kogoś, kto pisze styl, znajduję długie historie, takie jak to, które są naprawdę pobłażliwe i nieco nieodpowiednie poza osobistym blogiem.
16 LLlAMnYP 12/01/2017
@ T.Sar nie słuchajcie nienawidzących, wasz post jest klejnotem użytecznych rad od guru. +1
7 Mat's Mug 12/01/2017
"Architektura oprogramowania jest jak ser" była po prostu niesamowita. Rzeczywiście, ta odpowiedź jest klejnotem!
3 fede s. 12/01/2017
Może ta odpowiedź też jest jak ser? ;) Ale proszę, "SmallTalk" powinno być "Smalltalk", i tak, jestem that gościem, przepraszam.

doubleYou 11/30/2017.

Przede wszystkim powinieneś starać się przewidzieć, czy jest prawdopodobne, że taka zmiana wystąpi - nie tylko odległej możliwości gdzieś w dole.

Jeśli nie, zazwyczaj lepiej jest wybrać proste rozwiązanie i rozszerzyć je później. Jest całkiem możliwe, że będziesz miał bardziej przejrzysty obraz tego, co jest potrzebne.


Zapadlo 11/30/2017.

Jeśli pracujesz w domenie, która jest dla ciebie nowa, to zdecydowanie powinieneś zastosować Zasady 3. , o których wspomniał Daniel Pryden. W końcu, jak masz budować przydatne abstrakcje, jeśli jesteś nowicjuszem w tej dziedzinie? Ludzie często są pewni swojej zdolności do łapania abstrakcji, choć rzadko tak jest. Z mojego doświadczenia wynika, że ​​przedwczesna abstrakcja jest nie mniej zła niż duplikacja kodu. Złe abstrakcje są naprawdę bolesne do zrozumienia. Czasem jeszcze bardziej bolesne dla refaktora.

Jest książka poświęcona mojej sprawie o nieznanym obszarze, w którym pracuje programista. Składa się z określonych domen z wyodrębnionymi użytecznymi abstrakcjami.

4 comments
RibaldEddie 11/30/2017
Pytanie jasno dotyczy konkretnego problemu.
4 Zapadlo 11/30/2017
Odpowiedź jest na tyle ogólna, aby rozwiązać ten konkretny problem. Pytanie nie jest wystarczająco szczegółowe, aby otrzymać konkretny rachunek: jak widać, żadne dane dotyczące domeny nie są wymienione w pytaniu. Nawet nazwy klas nie są określone (A i B się nie liczą).
7 Lyndon White 12/01/2017
"Czy odpowiedź typu stackoverflow powinna być tak ogólna, jak to możliwe lub jak najbardziej konkretna?"
no comprende 12/01/2017
@LyndonWhite powinno być pytanie stackoverflow możliwie jak najbardziej ogólne (zbyt szerokie!) Lub tak szczegółowe, jak to możliwe (cokolwiek, że jest to wezwanie!)? Ha.

DrunkCoder 11/30/2017.

Biorąc pod uwagę naturę waszego pytania, zakładając, że rozumiem to poprawnie, uważam to za kwestię projektową systemu centralnego za coś więcej niż pytanie o rozwiązania rodzajowe a konkretne.

A jeśli chodzi o funkcje i możliwości systemu centralnego, najbardziej niezawodne są te, których nie ma. Opłaca się po stronie minimalizmu, zwłaszcza biorąc pod uwagę, że na ogół łatwiej jest dodawać funkcjonalność centralnie, długo pożądaną, niż usunąć problemową funkcjonalność, długo niepożądaną, z licznymi zależnościami, ponieważ dzięki temu praca z systemem stała się o wiele trudniejsza niż przy każdym nowym projekcie z niekończącymi się pytaniami projektowymi.

W rzeczywistości, nie mając dużego oczekiwania na to, czy będzie to często potrzebne w przyszłości, starałbym się nie patrzeć na to jako na typ zastępczy od A do B, jeśli to możliwe, a zamiast tego po prostu szukać go jako sposobu na przekształcenie państwa A. Na przykład, ustaw niektóre pola w A, aby zmieniły się i wyglądają jak B dla użytkownika, nie zmieniając się w inny "typ" rzeczy - możesz potencjalnie zrobić prywatny sklep B używając funkcji składu i wywołania w B, gdy stan A jest ustawiony, aby wskazywał, że powinien on naśladować B, aby w miarę możliwości uprościć implementację. To powinno być bardzo proste i minimalnie inwazyjne rozwiązanie.

W każdym razie, powtarzając wiele innych, sugerowałbym, by w tym przypadku unikać rozwiązań ogólnych, ale uważam, że jest to związane z dodaniem do centralnego systemu bardzo śmiałych możliwości, i sugerują, by porzucić to, szczególnie na teraz.

1 comments
no comprende 12/01/2017
"tęsknisz za wszystkimi błędami, których nie kodujesz." (z plakatu na koszykówkę: tęsknisz za wszystkimi ujęciami, których nie bierzesz)

Christophe 11/30/2017.

Trudno podać ogólną odpowiedź na ten konkretny problem ;-)

Im bardziej ogólny, tym więcej czasu zyskasz na przyszłe zmiany. Na przykład z tego powodu wiele programów do gier używa wzorca komponentu encji, zamiast budować bardzo rozbudowany, ale sztywny system postaci i obiektów w grze.

Z drugiej strony, zrobienie czegoś rodzajowego wymaga inwestowania z wyprzedzeniem i wysiłku w projekt, który jest znacznie wyższy niż w przypadku czegoś bardzo specyficznego. Niesie to ryzyko nadmiernej inżynierii, a nawet gubienia się w potencjalnych przyszłych wymaganiach.

Zawsze warto zobaczyć, czy istnieje naturalne uogólnienie, które doprowadzi cię do przełomu. Koniec końców, jest to kwestia równowagi między wysiłkiem, który możesz teraz wydać, a wysiłkiem, którego możesz potrzebować w przyszłości.


Adrian McCarthy 11/30/2017.
  1. Hybrydowy. To nie musi być jedno / lub pytanie. Możesz zaprojektować interfejs API dla ogólnych typów konwersji, jednocześnie realizując tylko określoną konwersję, której potrzebujesz teraz. (Wystarczy się upewnić, że jeśli ktoś wywoła ogólny interfejs API z nieobsługiwaną konwersją, nie powiedzie się ze statusem błędu "nieobsługiwany").

  2. Testowanie. Do konwersji A-> B będę musiał napisać jedną (lub małą liczbę) testów. Dla ogólnej konwersji x-> y, mógłbym napisać całą macierz testów. To znacznie więcej pracy, nawet jeśli wszystkie konwersje mają jedną ogólną implementację.

    Jeśli, z drugiej strony, okaże się, że jest to ogólny sposób testowania wszystkich możliwych konwersji, to nie ma zbyt wiele pracy i być może wcześniej skłonny byłbym pójść do rozwiązania ogólnego.

  3. Sprzęganie. Konwerter od A do B może koniecznie znać szczegóły implementacji A i B (ścisłe sprzężenie). Jeśli A i B wciąż się rozwijają, oznacza to, że będę musiał nadal przeglądać konwerter (i jego testy), co jest do bani, ale przynajmniej ogranicza się do A i B.

    Gdybym poszedł z ogólnym rozwiązaniem, które potrzebuje dostępu do szczegółów wszystkich typów, to nawet w miarę ewolucji C i D, być może będę musiał dalej modyfikować ogólny konwerter (i kilka testów), co może spowolnić mnie nawet chociaż nikt jeszcze nie musi konwertować na C lub D.

    Jeśli zarówno ogólne, jak i konkretne konwersje mogą zostać zaimplementowane w sposób luźno powiązany ze szczegółami typów, nie martwię się o to. Jeśli jedno z nich można zrobić w luźny sposób, ale drugie wymaga ścisłego sprzężenia, to jest to mocny argument dla luźno powiązanego podejścia tuż za bramą.

2 comments
2 leftaroundabout 11/30/2017
Testowanie to dobry punkt. To duża zaleta, jeśli projektujesz ogólne rozwiązania oparte na pojęciach z teorii kategorii , ponieważ często dostajesz darmowe twierdzenia, które dowodzą, że jedyną możliwą implementacją dla podpisu (którą akceptuje sprawdzarka typu kompilatora) jest the correct one , lub przynajmniej że jeśli algorytm działa dla określonego typu, musi również działać dla wszystkich pozostałych typów.
Ralf Kleberhoff 12/01/2017
Domyślam się, że istnieje specyficzny dla domeny powód, dla którego zażądano tylko jednej konwersji typu, co oznacza, że ​​większość konwersji typu to nieprawidłowe działania w domenie problemowej iz tego powodu aplikacja nie powinna być obsługiwana, dopóki są oficjalnie dozwolone. Odpowiedzi te są najbliższe tej argumentacji.

Useless 12/01/2017.

Czy rozwiązanie powinno być jak najbardziej ogólne lub jak najbardziej szczegółowe?

To nie jest odpowiadające pytanie.

Najlepszą rzeczą, jaką można rozsądnie uzyskać, jest kilka heurystyk, które decydują o tym, jak ogólny lub konkretny jest dany roztwór. Przetwarzając coś podobnego do poniższego procesu, zwykle przybliżenie pierwszego rzędu jest poprawne (lub wystarczająco dobre). Gdy nie jest, przyczyna może być zbyt specyficzna dla danej domeny, aby można ją było szczegółowo omówić tutaj.

  1. Aproksymacja pierwszego rzędu: zwykła zasada YAGNI w trzech przypadkach opisana przez Daniela Pryden, Doc Brown, et al .

    Jest to generalnie użyteczna heurystyka, ponieważ jest prawdopodobnie najlepszą możliwą czynnością, doesn't zależy od domeny i innych zmiennych.

    Tak więc początkowe założenie jest następujące: robimy najbardziej konkretną rzecz.

  2. Przybliżenie drugiego rzędu: na podstawie wiedzy eksperckiej dotyczącej solution domain , mówisz

    "Ogólne" rozwiązanie w tym przypadku wymaga mniej pracy niż "konkretne" rozwiązanie

    więc możemy ponownie zinterpretować YAGNI jako zalecenie, aby uniknąć niepotrzebnej work , zamiast unikać niepotrzebnej ogólności. Więc możemy zmodyfikować nasze początkowe założenie i zamiast tego zrobić easiest rzecz.

    Jeśli jednak wiedza na temat domeny rozwiązania wskazuje, że najprostsze rozwiązanie może otworzyć wiele błędów lub trudno je odpowiednio przetestować lub spowodować jakikolwiek inny problem, łatwiejsze jest kodowanie niekoniecznie jest wystarczającym powodem do zmiany naszego oryginalny wybór.

  3. Aproksymacja trzeciego rzędu: czy twoja wiedza na temat problem domain sugeruje, że najłatwiejsze rozwiązanie jest rzeczywiście poprawne, czy pozwalasz wielu przejściom, które uważasz za bezsensowne lub błędne?

    Jeśli proste, ale generyczne rozwiązanie wygląda na problematyczne lub nie jesteś pewny, czy potrafisz ocenić to ryzyko, to wykonanie dodatkowej pracy i pozostanie przy pierwszym podejściu jest prawdopodobnie lepsze.

  4. Przybliżenie na podstawie czwartego rzędu: czy twoja wiedza na temat zachowań klientów lub tego, w jaki sposób ta funkcja odnosi się do innych, czy priorytety w zarządzaniu projektami, czy też ... jakiekolwiek inne nie-ściśle techniczne rozważania modyfikują twoją obecną decyzję roboczą?


Cort Ammon 12/01/2017.

Na to proste pytanie nie można odpowiedzieć łatwo. Wiele odpowiedzi dało heurystyki zbudowane wokół reguły 3 lub czegoś podobnego. Wykroczenie poza takie zasady jest trudne.

Aby naprawdę odpowiedzieć na twoje pytanie, musisz wziąć pod uwagę, że twoja praca najprawdopodobniej nie wprowadzi czegoś, co zmienia A-> B. Jeśli jesteś wykonawcą, może taki jest wymóg, ale jeśli jesteś pracownikiem, zostałeś zatrudniony do wykonania wielu mniejszych zadań dla firmy. Zmiana A-> B jest tylko jednym z tych zadań. Twoja firma będzie troszczyć się o to, jak dobrze można dokonać przyszłych zmian, nawet jeśli nie jest to określone w żądaniu. Aby znaleźć "TheBestImplementation (tm)", musisz przyjrzeć się szerszemu obrazowi tego, o co naprawdę cię proszono, a następnie użyć tego do zinterpretowania małej prośby o zmianę A-> B.

Jeśli jesteś programistą niskiego poziomu, świeżo po studiach, często zaleca się wykonanie dokładnie tego, co ci kazano. Jeśli zostałeś zatrudniony jako architekt oprogramowania z 15-letnim doświadczeniem, zazwyczaj dobrze jest myśleć o dużych obrazach. Każda rzeczywista praca spadnie gdzieś pomiędzy "wykonaj dokładnie to, co jest wąskim zadaniem" i "pomyśl o wielkim obrazie". Poczujesz, że twoja praca pasuje do tego spektrum, jeśli rozmawiasz z ludźmi wystarczająco dużo i robisz dla nich wystarczająco dużo pracy.

Mogę podać kilka konkretnych przykładów, w których twoje pytanie ma ostateczną odpowiedź na podstawie kontekstu. Weź pod uwagę przypadek, w którym piszesz oprogramowanie o znaczeniu krytycznym dla bezpieczeństwa. Oznacza to, że masz zespół testowy, aby upewnić się, że produkt działa zgodnie z obietnicą. Niektóre z tych zespołów testowych są zobowiązane do przetestowania każdej możliwej ścieżki za pomocą kodu. Jeśli z nimi porozmawiasz, może się okazać, że generalizując zachowanie, dodasz 30 000 USD do swoich kosztów testowania, ponieważ będą musieli przetestować wszystkie dodatkowe ścieżki. W takim przypadku do not dodawaj uogólnionej funkcjonalności, nawet jeśli musisz z tego powodu powielać pracę 7 lub 8 razy. Zaoszczędź pieniądze firmy i wykonaj dokładnie to, o czym wspomniał wniosek.

Z drugiej strony zastanów się, czy tworzysz interfejs API, aby umożliwić klientom dostęp do danych w programie bazodanowym firmy. Klient prosi o zezwolenie na zmiany A-> B. Interfejsy API mają zazwyczaj aspekt złotych kajdanek: po dodaniu funkcjonalności do interfejsu API zazwyczaj nie powinno się usuwać tej funkcji (do następnego numeru głównej wersji). Wielu klientów może nie być gotowych zapłacić za aktualizację do kolejnego ważnego numeru wersji, więc może utknąć w dowolnym rozwiązaniu przez długi czas. W tym przypadku highly polecam stworzenie ogólnego rozwiązania od samego początku. Naprawdę nie chcesz tworzyć złego API pełnego jednorazowych zachowań.


Hans-Peter Störr 12/05/2017.

Dla mnie wytyczną, którą ustaliłem jakiś czas temu, jest: "Dla hipotetycznych wymagań pisz tylko hipotetyczny kod". To znaczy - jeśli przewidujesz dodatkowe wymagania, powinieneś pomyśleć trochę o tym, jak je wdrożyć, i ustrukturyzuj swój obecny kod, aby nie blokował w ten sposób.

Ale nie pisz tego teraz - po prostu pomyśl trochę o tym, co byś zrobił. W przeciwnym razie zazwyczaj sprawisz, że będzie to niepotrzebnie skomplikowane i prawdopodobnie będziesz denerwować się później, gdy pojawią się rzeczywiste wymagania, które różnią się od przewidywanych.

Czwarty twój przykład: jeśli masz pod kontrolą wszystkie zastosowania metody konwersji, możesz po prostu nazwać ją convertAToB na teraz i planujesz użyć refaktoryzacji "metody zmiany nazwy" w IDE, aby zmienić jej nazwę, jeśli potrzebujesz późniejszej ogólnej funkcjonalności. Jednakże, jeśli metoda konwersji jest częścią publicznego interfejsu API, może to wyglądać zupełnie inaczej: bycie takim blokowałoby później generalizację, ponieważ w tym przypadku trudno jest zmienić nazwy rzeczy.


railsdog 12/01/2017.

Hmm ... mało kontekstu do odpowiedzi ... echo wcześniejszych odpowiedzi, "to zależy".

W pewnym sensie musisz powrócić do swojego doświadczenia. Jeśli nie twój, to ktoś starszy w domenie. Można spierać się o to, jakie kryteria akceptacji są spełnione. Jeśli jest to coś w rodzaju "użytkownik powinien móc zmienić typ z" A "na" B "w porównaniu do" użytkownik powinien móc zmienić typ z jego bieżącej wartości na dowolną dozwoloną wartość alternatywną ".

Często kryteria akceptacji podlegają interpretacji, ale dobry personel QA może napisać kryteria odpowiednie do danego zadania, minimalizując wymaganą interpretację.

Czy istnieją ograniczenia domenowe, które nie pozwalają na zmianę z "A" na "C" lub jakiejkolwiek innej opcji, ale tylko "A" na "B"? Czy jest to tylko wąsko określone wymaganie, które nie jest "przyszłym myśleniem"?

Jeśli ogólny przypadek byłby trudniejszy, zapytałbym go przed rozpoczęciem pracy, ale w twoim przypadku, gdybym mógł "przewidzieć", że inne żądania zmiany typu pojawią się w przyszłości, byłbym skłonny: a) napisz coś możliwego do wielokrotnego użycia w ogólnym przypadku, i b) zawiń to w warunek, który zezwala tylko na A -> B na teraz.

Wystarczająco łatwe do zweryfikowania w bieżącym przypadku w testach automatycznych i łatwe do otwarcia na inne opcje w późniejszym czasie, jeśli pojawią się różne przypadki użycia.


AnoE 12/03/2017.

Wciąż słyszę, że dobry programista powinien starać się przewidzieć zmianę i zaprojektować system, aby można go było łatwo rozszerzyć w przyszłości,

Zasadniczo tak. Ale niekoniecznie prowadzi to do ogólnych rozwiązań.

Są dwa rodzaje tematów w rozwoju oprogramowania, o ile mi wiadomo, gdzie należy przewidzieć przyszłe zmiany:

  • Biblioteki przeznaczone do użytku przez strony trzecie, oraz
  • ogólna architektura oprogramowania.

Pierwszy przypadek rozwiązuje się, obserwując twoją spójność / sprzężenie, zastrzyk zależności lub cokolwiek innego. Drugi przypadek znajduje się na bardziej abstrakcyjnym poziomie, na przykład wybierając architekturę zorientowaną na usługi zamiast dużego monobotycznego blobu kodu dla dużej aplikacji.

W twoim przypadku prosisz o konkretne rozwiązanie konkretnego problemu, który nie ma żadnego możliwego do przewidzenia wpływu na przyszłość. W tym przypadku YAGNI i DRY są dobrymi motkami do strzelania:

  • YAGNI (nie będziesz tego potrzebował) mówi, żebyś wdrożył absolutnie minimum, podstawowe rzeczy, których potrzebujesz i używasz right now . Oznacza to wdrożenie minimum, które sprawia, że ​​twój obecny zestaw testów zmienia się z czerwonego na zielony, jeśli powinieneś używać rozwoju stylu TDD / BDD / FDD. Ani jednej linii więcej.
  • DRY (nie powtarzaj się) oznacza, że ​​jeśli ponownie pojawi się podobny problem, dobrze się przyjrzysz, czy potrzebujesz ogólnego rozwiązania.

W połączeniu z innymi nowoczesnymi praktykami (takimi jak dobry zasięg testów, aby móc bezpiecznie refaktoryzować), oznacza to, że otrzymujesz szybko napisany, szczupły, średni kod, który rośnie w miarę potrzeb.

co brzmi jak ogólne rozwiązanie to droga?

Nie, wygląda na to, że powinieneś mieć środowiska programistyczne, języki i narzędzia, które ułatwiają i ułatwiają refaktoryzację w razie potrzeby. Ogólne rozwiązania tego nie zapewniają; oddzielają aplikację od rzeczywistej domeny.

Spójrz na nowoczesne środowiska ORM lub MVC, na przykład Ruby on Rails; na poziomie aplikacji skupiamy się na wykonywaniu nietypowych prac. Same biblioteki szyn są oczywiście w przybliżeniu w 100% generyczne, ale kod domeny (o którym mowa) powinien w tym aspekcie robić minimalną liczbę shenaniganów.


Robert Baron 12/03/2017.

Innym sposobem myślenia o problemie jest rozważenie, co ma sens.

Przykładem była aplikacja, którą opracowywałem, która zawierała sekcje, które zawierały prawie to samo, ale miały niespójne reguły uprawnień. Ponieważ nie było powodu, aby je odmienid, kiedy refaktoryzowałem tę sekcję, kazałem im wszystkim robić pozwolenia w ten sam sposób. Dzięki temu ogólny kod był mniejszy, prostszy, a interfejs był bardziej spójny.

Kiedy kierownictwo postanowiło zezwolić innym osobom na dostęp do funkcji, byliśmy w stanie to zrobić po prostu zmieniając flagę.

Oczywiście ma sens konwersja określonego typu. Czy ma sens także konwersja typu addintional?

Należy pamiętać, że jeśli ogólne rozwiązanie jest szybsze do wdrożenia, to właściwy przypadek jest łatwy, wystarczy sprawdzić, czy jest to jedyna możliwa konwersja.

Jeśli aplikacja znajduje się na wysoce regulowanym obszarze (aplikacja medyczna lub finansowa), spróbuj zaangażować więcej osób w projekt.


HighResolutionMusic.com - Download Hi-Res Songs

1 BLACKPINK

Kiss And Make Up flac

BLACKPINK. 2018. Writer: Soke;Kny Factory;Billboard;Chelcee Grimes;Teddy Park;Marc Vincent;Dua Lipa.
2 Martin Garrix

Access flac

Martin Garrix. 2018. Writer: Martin Garrix.
3 Martin Garrix

Yottabyte flac

Martin Garrix. 2018. Writer: Martin Garrix.
4 Dyro

Latency flac

Dyro. 2018. Writer: Martin Garrix;Dyro.
5 Martin Garrix

Waiting For Tomorrow flac

Martin Garrix. 2018. Writer: Pierce Fulton;Mike Shinoda;Martijn Garritsen;Brad Delson.
6 Alan Walker

Diamond Heart flac

Alan Walker. 2018. Writer: Alan Walker;Sophia Somajo;Mood Melodies;James Njie;Thomas Troelsen;Kristoffer Haugan;Edvard Normann;Anders Froen;Gunnar Greve;Yann Bargain;Victor Verpillat;Fredrik Borch Olsen.
7 Bradley Cooper

Shallow flac

Bradley Cooper. 2018. Writer: Andrew Wyatt;Anthony Rossomando;Mark Ronson;Lady Gaga.
8 Cardi B

Taki Taki flac

Cardi B. 2018. Writer: Bava;Juan Vasquez;Vicente Saavedra;Jordan Thorpe;DJ Snake;Ozuna;Cardi B;Selena Gomez.
9 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
10 Sia

I'm Still Here flac

Sia. 2018. Writer: Sia.
11 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
12 Blinders

Breach (Walk Alone) flac

Blinders. 2018. Writer: Dewain Whitmore;Ilsey Juber;Blinders;Martin Garrix.
13 Dewain Whitmore

Burn Out flac

Dewain Whitmore. 2018. Writer: Dewain Whitmore;Ilsey Juber;Emilio Behr;Martijn Garritsen.
14 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
15 Avril Lavigne

Head Above Water flac

Avril Lavigne. 2018. Writer: Stephan Moccio;Travis Clark;Avril Lavigne.
16 Mako

Rise flac

Mako. 2018. Writer: Riot Music Team;Mako;Justin Tranter.
17 ZAYN

Fingers flac

ZAYN. 2018. Writer: Zayn Malik;Alex Oriet;David Phelan.
18 Billie Eilish

When The Party's Over flac

Billie Eilish. 2018. Writer: Billie Eilish;FINNEAS.
19 Kelsea Ballerini

This Feeling flac

Kelsea Ballerini. 2018. Writer: Andrew Taggart;Alex Pall;Emily Warren.
20 Zara Larsson

Ruin My Life flac

Zara Larsson. 2018. Writer: Delacey;Michael Pollack;Stefan Johnson;Jordan Johnson;Sermstyle;Jackson Foote.

Related questions

Hot questions

Language

Popular Tags