Wartości domyślne - czy są dobre czy złe?

12

Pytanie o wartości domyślne w ogóle - domyślne wartości funkcji zwracanych, domyślne wartości parametrów, domyślna logika dla czegoś, czego brakuje, domyślna logika do obsługi wyjątków, domyślna logika do obsługi warunków brzegowych itp.

Przez długi czas uważałem wartości domyślne za „czyste zło”, coś, co „maskuje katastrofę” i powoduje, że bardzo trudno znaleźć błędy. Ale ostatnio zacząłem myśleć o wartościach domyślnych jako pewnego rodzaju długu technicznym ... co nie jest po prostu złą rzeczą, ale czymś, co może zapewnić pewne „krótkoterminowe finansowanie”, które zmusi nas do przetrwania projektu (na ile z nas stać kupić dom bez zaciągania kredytu hipotecznego?).

Kiedy mówię „krótkookresowo” - nie mam na myśli - „najpierw zrób coś szybko, a potem przerób to później, zanim trafi do produkcji”. Nie - mówię o poleganiu na zakodowanych wartościach domyślnych w oprogramowaniu produkcyjnym. To prawda - może powodować pewne problemy, ale co jeśli spowoduje tylko jeden problem w ciągu całego roku.

Znowu - mówię o „przeciętnym” oprogramowaniu głównego nurtu (nie oprogramowaniu dla elektrowni jądrowej) - przeciętnej stronie internetowej lub aplikacji interfejsu użytkownika dla oprogramowania księgowego, co oznacza, że ​​ludzie nie są zagrożeni ani miliony dolarów .

Z mojego doświadczenia wynika, że ​​użytkownicy biznesowi wolą żyć z oprogramowaniem, które „jakoś działa”, zamiast czekać na idealne. A użycie wartości domyślnych bardzo pomaga, jeśli tworzysz oprogramowanie w stylu RAD. Ale znowu - najdłuższe sesje debugowania, które spędziłem, były spowodowane błędami wprowadzonymi przez wartość domyślną, która albo przestała być „domyślną” po drodze, albo dlatego, że niedawno zaktualizowano mały podsystem, a w wyniku tego uaktualnienia nie poprawnie obsługuje domyślną wartość (np. pusta lista vs. null lub ciąg zerowy vs pusty ciąg).

Więc moje pytanie brzmi - czy wartości domyślne są dobre czy złe? A jeśli są to zadłużenie techniczne - jak zmierzyć, ile możesz pożyczyć, aby pozwolić sobie na spłaty?

Byłbym wdzięczny za każdy wkład.

Twoje zdrowie.

EDYTOWAĆ:

Jeśli używam wartości domyślnych jako sposobu na zmniejszenie narożników podczas opracowywania - i jeśli cięcie narożników powoduje błędy i problemy - jaka jest metodologia, aby rozwiązać te problemy?


źródło

Odpowiedzi:

23

Koncepcja konwencji o konfiguracji jest niemożliwa bez rozsądnych wartości domyślnych. Kluczowym słowem jest tutaj „rozsądny”. Wartości domyślne muszą mieć sens dla co najmniej 80% (jeśli nie więcej) wszystkich zastosowań biblioteki / usługi / frameworka.

Ogólne zasady praktyczne:

  • Jeśli wartość jest sensowna dla 80% lub więcej zastosowań, musi być wartością domyślną
  • Jeśli w większości przypadków nie ma żadnych wartości, nie należy używać wartości domyślnych.
  • Wartości domyślne zapobiegają głupim błędom w kodzie instalacyjnym. Jeśli wartości domyślne są uzasadnione w większości przypadków, mniej osób ma problemy z działającą konfiguracją.
  • Niestandardowe konfiguracje są bardziej widoczne przy użyciu ustawień domyślnych.
  • Złe wartości domyślne są gorsze niż brak wartości domyślnych.

Zasadniczo, gdy nauczysz się, jak działa konfiguracja domyślna, możesz podejmować świadome decyzje dotyczące tego, jak / kiedy wykonać konfiguracje niestandardowe.

Berin Loritsch
źródło
Dziękujemy za wskazanie mi koncepcji „Konwencja o konfiguracji”. Użyłem go, nie wiedząc, że ma nazwę. Czy możesz wyjaśnić tę zasadę: „Niestandardowe konfiguracje są bardziej widoczne przy użyciu ustawień domyślnych”. Proszę.
3
@Andrew, jeśli jest tuzin połączeń Foo()i jedno połączenie Foo("bar"), to jedno połączenie ma tendencję do wyróżniania się i dlatego jest bardziej widoczne.
Matthew Scharley
1
Racja, a jeśli większość zastosowań usługi FTP używa new FtpService()tego, który ustawia alternatywny port, będzie się wyróżniał ( service.SetPort(12345)).
Berin Loritsch
43

Weźmy na przykład bibliotekę, która implementuje protokół FTP. Domyślnie FTP ma działać na porcie 21. Teraz byłbym bardzo zirytowany, gdybym musiał określić użycie portu 21 za każdym razem, gdy buduję obiekt losowej klasy FTP. Jeśli potrzebuję innego portu, pozwól mi określić.

Domyślne wartości są w porządku, gdy są rozsądne.

Htbaa
źródło
21
+1. Kiedy ostatni raz wpisałeś http://programmers.stackexchange.com:80/questions/?sort=newest&pagesize=50w pasek adresu?
Jörg W Mittag
1
Jak mierzyć / szacować / ect poziom poczytalności zmiennej domyślnej.
5
Ile czasu zajmuje wymyślenie rozsądnej wartości domyślnej.
Alexander Gessler
1
@Andrew, zobacz moją odpowiedź poniżej. Jeśli wartość jest dobra dla 80% lub więcej zastosowań, jest to dobra wartość domyślna.
Berin Loritsch
2
@Berin Loritsch: Jeśli wartość domyślna jest używana do bezpiecznego niepowodzenia, możesz argumentować, że jest dobra, nawet jeśli jest używana tylko przez 1% czasu.
oosterwal
18

Prawdopodobnie używasz domyślnego układu klawiatury z domyślnymi odwzorowaniami klawiszy, domyślnymi odwzorowaniami przycisków myszy, domyślną przeglądarką, wpisując w domyślnym języku systemowym, uruchamianie z domyślnego systemu operacyjnego w module ładującym, domyślnie pozycjonowane menu, domyślny schemat kolorów, domyślna czcionka szerokość / wysokość / twarz / styl, domyślny zestaw znaków, domyślna rozdzielczość monitora, domyślnie ... masz pomysł.

Ale z całą powagą, myślę, że twoja troska nie dotyczy domyślnych, ale czegoś innego. Domyślne zachowanie z natury nie maskuje błędów. W każdym razie Twój kod i tak będzie działał w typowych warunkach, niezależnie od tego, czy ustawisz wartości domyślne. Nieobsługiwane przypadki brzegowe to rzeczy, których będziesz chciał się upewnić, niezależnie od tego (prawdopodobnie poprzez odpowiednie i właściwe testowanie), na przykład, gdy zmienią się wartości domyślne lub zdarzy się niezwykły scenariusz.

Ponadto obsługa wyjątków typu „catch-all” jest prawdopodobnie wadą projektową, a nie czymkolwiek, co można nazwać „domyślnym”.

Rei Miyasaka
źródło
OK, „catch-all” faktycznie jest dobrym przykładem. Tak - wywołuje to wielki smutek, gdy pewnego dnia coś idzie nie tak z jakiegoś nieznanego powodu, a ci „niektórzy” są nieznani głównie dlatego, że prawdziwy wyjątek został utracony w bloku typu catch-all. Więc to jest zła rzecz - prawda? Z drugiej strony - bez bloku typu catch-all oprogramowanie może całkowicie umrzeć (jeśli wyjątek nie zostanie obsłużony) lub wymagałoby skomplikowanej logiki obsługi błędów (przynajmniej musiałby zarejestrować wyjątek i zainicjować niektóre dane za pomocą wartości domyślne).
Tak więc, aby dodać do mojego pierwotnego pytania - jeśli używam wartości domyślnych jako sposobu na zmniejszenie narożników podczas opracowywania - i jeśli cięcie narożników powoduje błędy i problemy - jaki jest najlepszy sposób na rozwiązanie tych problemów?
1
Jeśli chodzi o wyjątki, jest artykuł, który mówi, że powinien istnieć jeden wyjątek typu catch-all na wątek , jeśli w ogóle. Byłby używany do raportowania błędów, więc patrzysz na program jako pojedynczą „rzecz” tak samo, jak system operacyjny postrzegałby proces. Ponieważ w pętli znajduje się użytkownik końcowy (i mam nadzieję, że programiści), tak naprawdę nie „połykasz” wyjątku - więc wszystko jest w porządku. Artykuł tutaj: codeproject.com/KB/architecture/exceptionbestpractices.aspx
Rei Miyasaka
1
Jeśli chodzi o używanie ustawień domyślnych w celu uniknięcia błędów - co powiesz na stosowanie spójnego komentarza, dla którego możesz kontrolować + f / mac + f? Na przykład Visual Studio faktycznie pokazuje każdy komentarz, który zaczyna się TODO: or TEMP:na liście zadań. Jeśli kiedykolwiek wycinam róg ze względu na rozwój, staram się bardzo uważać, aby umieścić tam TODO - wtedy od czasu do czasu zrobię „znajdź wszystko”, aby wrócić i upewnić się nic z tego nie wchodzi w żadne ważne kompilacje.
Rei Miyasaka,
Ups, miałem na myśli użycie zakodowanych wartości, aby pomóc w rozwoju. Nawiasem mówiąc, właśnie zdałem sobie sprawę, że „wartości zakodowane na stałe” to prawdopodobnie słowo, którego szukasz, a nie „wartości domyślne”.
Rei Miyasaka,
3

Wartości domyślne powinny być stosowane, gdy zapisują one użytkownika lub programistę przed wykonywaniem powtarzalnych zadań. Nigdy nie należy ich używać do maskowania błędów lub wyjątków. Używanie ich w celu zapobiegania błędom nie jest złą praktyką, ale tylko o ile zapobieganie nie maskuje czegoś złego. Wartości domyślne są narzędziem, podobnie jak wszystko inne. Właściwie zastosowane mogą zaoszczędzić wiele bólu głowy i czasu. Niewłaściwie użyte mogą sprowadzić cały dom na dół.

Joel Etherton
źródło
Coś jak C ++ zdmuchujący całą nogę ...
Mateen Ulhaq,
1
@muntoo: Hej, Lisp utykałem w '03.
Joel Etherton,
3

Główną przyczyną cytowanych problemów nie są same wartości domyślne, ale problemy z integracją wynikające ze zmiany umów interfejsu, nieporozumień interpretacyjnych i / lub błędnych założeń. Zasadniczo wszystkie te (konkretne przykłady) wydają się być wynikiem niewłaściwej komunikacji - między klientem a programistą lub między różnymi programistami / zespołami. W porządku, problemy te mogą objawiać się jako nieprawidłowe wartości domyślne, ale także w niezliczonych innych postaciach.

Zajmij się pierwotną przyczyną, a nie objawem.

Zwróć też uwagę, że - jak zauważyli inni z doskonałymi przykładami - wartości domyślne, gdy są mądrze stosowane, mogą znacznie ułatwić życie użytkownikom. I to jest ostatecznie nasz cel, prawda?

Péter Török
źródło
„Nieprawidłowa komunikacja” może być podstawową przyczyną, ale czy nie jest podstawową przyczyną prawie wszystkiego? A ponieważ „moim ostatecznym celem” jest dostarczanie „wystarczająco dobrego” oprogramowania na czas w środowisku o ograniczonych kosztach, chciałem wiedzieć, jak odróżnić złe / złe od domyślnych.
@Andrew, komunikacja (lub jej brak) jest głównym czynnikiem powodzenia / niepowodzenia projektu, ale daleki od bycia jedynym. Jednak gdy jest to winowajcą, należy sobie z tym poradzić właściwie, w przeciwnym razie projekt jest prawie na pewno skazany na niepowodzenie. Nie znam żadnego magicznego narzędzia do oddzielania złych wartości domyślnych od dobrych: IMHO wymaga starannej analizy domeny problemu, przypadków użycia itp. I, no cóż, dużej ilości komunikacji.
Péter Török,
1

Domyślne wartości, które nie są częścią protokołu / konwencji komunikacji, są złe. Przez to, że „nie jest częścią”, mam na myśli, że nie są udokumentowane, gdzie protokół jest ścisły, lub po prostu nie oczekuje się, że protokół jest luźny.

Jeśli wartość domyślna jest udokumentowana / oczekiwana, nadal może być zła, ale może również zapewnić bezpieczne życie. To zależy od obszaru domeny. Bardzo często mogą być bardzo niebezpieczne (np. Domyślne dawkowanie leku, domyślna podłoga windy, domyślny kierunek ruchu samochodu), a czasem może być niebezpieczne, że ich nie ma (np. Domyślny kierunek ruchu samochodu, domyślny czas spotkania).

astef
źródło