[Uwaga: to pytanie jest subiektywne, ale wolałbym uzyskać odpowiedzi poparte faktami i / lub refleksjami]
Myślę, że wszyscy wiedzą o zasadzie solidności , zwykle podsumowanej przez prawo Postela:
Bądź konserwatywny w tym, co wysyłasz; bądźcie liberalni w tym, co akceptujecie.
Zgodziłbym się, że przy projektowaniu powszechnego protokołu komunikacyjnego może to mieć sens (w celu umożliwienia łatwego rozszerzenia), jednak zawsze uważałem, że jego zastosowanie do HTML / CSS było całkowitą porażką, każda przeglądarka wdrożyła własne ciche poprawki wykrywanie / zachowanie, co uniemożliwia uzyskanie spójnego renderowania w wielu przeglądarkach.
Zauważam jednak, że tam RFC protokołu TCP uznaje „cichą awarię” za dopuszczalną, chyba że określono inaczej ... co jest co najmniej ciekawym zachowaniem.
Istnieją inne przykłady zastosowania tej zasady w handlu oprogramowaniem, które regularnie pojawiają się, ponieważ ugryzły programistów, od samego początku:
- Wstawianie średników w JavaScript
- C (ciche) wbudowane konwersje (co nie byłoby takie złe, gdyby nie zostało obcięte ...)
i istnieją narzędzia, które pomogą wprowadzić „inteligentne” zachowanie:
- algorytmy fonetyczne dopasowujące nazwy ( Double Metaphone )
- algorytmy odległości ciągów ( odległość Levenshteina )
Uważam jednak, że takie podejście, chociaż może być pomocne w kontaktach z użytkownikami nietechnicznymi lub pomagać użytkownikom w procesie odzyskiwania błędów, ma pewne wady, gdy stosuje się je do projektowania interfejsu biblioteki / klas:
- jest nieco subiektywne, czy algorytm zgaduje „dobrze”, a zatem może być sprzeczne z zasadą najmniejszego zdziwienia
- utrudnia to wdrożenie, a tym samym zwiększa szanse na wprowadzenie błędów (naruszenie YAGNI ?)
- sprawia, że zachowanie jest bardziej podatne na zmianę, ponieważ każda modyfikacja procedury „zgadywania” może uszkodzić stare programy, prawie wykluczając możliwości refaktoryzacji ... od samego początku!
I to doprowadziło mnie do następującego pytania:
Czy projektując interfejs (bibliotekę, klasę, komunikat) kierujesz się zasadą niezawodności, czy nie?
Ja sam bywam dość rygorystyczny, korzystam z szerokiej weryfikacji danych wejściowych na moich interfejsach i zastanawiałem się, czy nie byłem może zbyt rygorystyczny.
Odpowiedzi:
Powiedziałbym solidność, gdy nie wprowadza ona dwuznaczności .
Na przykład: Podczas analizowania listy rozdzielanej przecinkami, to czy przed lub po przecinku jest spacja, nie zmienia znaczenia semantycznego.
Podczas parsowania łańcucha id powinien przyjmować dowolną liczbę popularnych formatów (z myślnikami lub bez myślników, z otaczającymi nawiasami klamrowymi lub bez nich).
Większość języków programowania jest odporna na użycie białych znaków. Szczególnie wszędzie tam, gdzie nie wpływa to na znaczenie kodu. Nawet w Pythonie, gdzie spacja jest istotna, nadal jest elastyczna, gdy znajdujesz się w deklaracji listy lub słownika.
Zdecydowanie zgadzam się, że jeśli coś można zinterpretować na wiele sposobów lub jeśli nie jest w 100% jasne, co miało na myśli, to zbyt duża wytrzymałość może skończyć się bólem, ale jest dużo miejsca na solidność bez dwuznaczności.
źródło
{"key": "value",}
jako prawidłowy, IE nie. Często napotykałem ten problem, dopóki nie poprawiłem procesu kompilacji za pomocą JSlint.Absolutnie nie. Techniki takie jak programowanie obronne zaciemniają błędy, przez co ich wygląd jest mniej prawdopodobny i bardziej losowy, co utrudnia ich wykrywanie, co utrudnia ich izolację.
Zdecydowanie niedoceniany Pisanie Solidnego Kodu był ogromny, ponieważ wielokrotnie podkreślał potrzebę i techniki uczynienia błędów tak trudnymi do wprowadzenia lub ukrycia. Poprzez zastosowanie jego zasad, takich jak: „Wyeliminuj przypadkowe zachowanie. Wymuś powtarzalność błędów”. oraz „Zawsze szukaj i eliminuj wady swoich interfejsów”. programiści znacznie poprawią jakość swojego oprogramowania, eliminując niejasności i niekontrolowane skutki uboczne, które są odpowiedzialne za dużą liczbę błędów.
źródło
Nadmierne zastosowanie niezawodności prowadzi do zgadywania, czego chciał użytkownik, co jest w porządku, dopóki się nie pomylisz. Wymaga to również całkowicie błędnej wiary, że Twoi klienci nie będą nadużywać Twojego zaufania i nie będą tworzyć przypadkowych bełkotów, które po prostu działają, ale których nie będziesz w stanie wspierać w wersji 2.
Nadmierne zastosowanie poprawności powoduje, że odmawiasz klientom prawa do popełniania drobnych błędów, co jest w porządku, dopóki nie narzekają, że ich produkty działają dobrze na produkcie konkurencji, i mówią ci, co możesz zrobić dzięki standardowi 5000 stron, który zawiera słowo „PROJEKT” nadal jest napisany kredką na okładce, a co najmniej 3 ekspertów twierdzi, że jest zasadniczo wadliwa, a 200 innych uczciwych ekspertów twierdzi, że nie do końca rozumie.
Moje osobiste rozwiązanie zawsze było zaniedbaniem. Wspierasz ich, ale mówisz im, że robią źle i (jeśli to możliwe) najłatwiejszą drogę do poprawności. W ten sposób, gdy wyłączysz tę funkcję błędu na 10 lat, będziesz miał przynajmniej ślad papierowy, aby stwierdzić, że „ostrzegaliśmy cię, że może się to zdarzyć”.
źródło
Niestety, tak zwana „zasada solidności” nie prowadzi do solidności. Weź HTML jako przykład. Można by uniknąć wielu kłopotów, łez, marnowania czasu i energii, gdyby przeglądarki od samego początku ściśle analizowały HTML, zamiast próbować odgadnąć znaczenie źle sformułowanej zawartości.
Przeglądarka powinna po prostu wyświetlić komunikat o błędzie zamiast próbować naprawić go pod przykryciem. Zmusiłoby to wszystkich bandytów do naprawienia bałaganu.
źródło
Interfejsy dzielę na kilka grup (dodaj więcej, jeśli chcesz):
Wynik zawsze musi być ścisły.
źródło
Myślę, że HTML i World Wide Web dostarczyły na szeroką skalę rzeczywistego testu zasady solidności i pokazały, że jest to ogromna awaria. Jest bezpośrednio odpowiedzialny za mylący bałagan konkurujących ze sobą prawie standardów HTML, który czyni życie nieszczęśliwym dla twórców stron internetowych (i ich użytkowników) i pogarsza się z każdą nową wersją Internet Explorera.
Od lat 50. wiemy, jak poprawnie sprawdzać poprawność kodu. Uruchom go przez ścisły parser, a jeśli coś nie jest poprawne pod względem składniowym, wyrzuć błąd i przerwij. Nie przechodź, nie zbieraj 200 $, a na miłość binarną nie pozwól, aby jakiś program komputerowy próbował odczytać myśli programisty, jeśli popełni błąd.
HTML i JavaScript pokazały nam dokładnie, co się dzieje, gdy zasady te są ignorowane. Najlepiej jest uczyć się na błędach i nie powtarzać ich.
źródło
Jako kontrapunkt dla przykładu Masona, moje doświadczenie z protokołem inicjującym sesję było takie, że podczas gdy różne stosy interpretowałyby odpowiednie RFC inaczej (i podejrzewam, że dzieje się tak z każdym standardem, jaki kiedykolwiek napisano), bycie (umiarkowanie) liberalnym w tym, co akceptujesz, oznacza, że ty może faktycznie nawiązywać połączenia między dwoma urządzeniami. Ponieważ te urządzenia są zwykle rzeczami fizycznymi, w przeciwieństwie do oprogramowania na pulpicie, po prostu musisz być liberalny w tym, co akceptujesz, w przeciwnym razie telefon nie będzie mógł zadzwonić na inny telefon określonej marki. To nie sprawia, że Twój telefon wygląda dobrze!
Ale jeśli piszesz bibliotekę, prawdopodobnie nie masz problemu z interpretowaniem przez wiele stron wspólnego standardu na wzajemnie niezgodne sposoby. W takim przypadku powiedziałbym, że zachowuj się surowo, ponieważ akceptuje to dwuznaczności.
Plik żargonu zawiera również horror o „odgadywaniu” intencji użytkownika.
źródło
Masz rację, reguła dotyczy protokołów, a nie programowania. Jeśli popełnisz literówkę podczas programowania, po kompilacji pojawi się błąd (lub uruchom, jeśli jesteś jednym z tych typów dynamicznych). Nie można nic zyskać, pozwalając komputerowi zgadywać. W przeciwieństwie do zwykłych ludzi, jesteśmy inżynierami i jesteśmy w stanie powiedzieć dokładnie, co mam na myśli. ;)
Tak więc, projektując API, powiedziałbym, że nie postępuj zgodnie z zasadą niezawodności. Jeśli programista popełni błąd, powinien natychmiast się o tym dowiedzieć. Oczywiście, jeśli Twój interfejs API wykorzystuje dane ze źródła zewnętrznego, takiego jak plik, powinieneś być łagodny. Użytkownik twojej biblioteki powinien dowiedzieć się o swoich błędach, ale nie o nikim innym.
Nawiasem mówiąc, zgaduję, że „cicha awaria” jest dozwolona w protokole TCP, ponieważ inaczej, gdyby ludzie rzucali w ciebie źle sformułowane pakiety, byłbyś bombardowany komunikatami o błędach. To prosta ochrona DoS.
źródło
IMO, solidność jest jedną ze stron kompromisu projektowego, a nie zasadą „preferuj”. Jak wielu zauważyło, nic nie śmierdzi niczym dmuchanie na cztery godziny, próbując dowiedzieć się, gdzie twój JS popełnił błąd, tylko po to, aby odkryć prawdziwy problem, ponieważ tylko jedna przeglądarka działała poprawnie z XHTML Strict. Dzięki temu strona rozpadła się na kawałki, gdy pewna część obsługiwanego HTML była kompletną katastrofą.
Z drugiej strony, kto chce poszukać dokumentacji dla metody, która bierze 20 argumentów i nalega, aby były one w tej samej kolejności z pustymi lub zerowymi symbolami zastępczymi dla tych, które chcesz pominąć? Równie okropnym, solidnym sposobem radzenia sobie z tą metodą byłoby sprawdzenie każdego argumentu i próba zgadnięcia, który z nich był oparty na względnych pozycjach i typach, a następnie zawiodła po cichu lub próba „zrekompensowania” bezsensownych argumentów.
Możesz też uelastycznić proces, przekazując listę literału obiektu / słownika / pary klucz-wartość i obsłużyć istnienie każdego argumentu, gdy do niego dojdziesz. Dla bardzo drobnego kompromisu jest to ciasto i zjadaj to też scenariusz.
Przeciążenie argumentów w inteligentny i spójny z interfejsem sposób to sprytny sposób na solidne podejście do rzeczy. Podobnie pieczenie nadmiarowości w systemie, w którym zakłada się, że dostarczanie pakietów nie będzie regularnie dostarczane w ogromnie skomplikowanej sieci będącej własnością i obsługiwanej przez wszystkich w rozwijającej się dziedzinie technologii z szeroką gamą potencjalnych środków transmisji.
Tolerowanie nadużycia, szczególnie w systemie, który kontrolujesz, nigdy nie jest dobrym kompromisem. Na przykład musiałem odetchnąć, aby uniknąć rzucenia syczącego napadu w innym pytaniu dotyczącym umieszczenia JS na górze lub na dole strony. Kilka osób nalegało, aby lepiej umieścić JS na górze, ponieważ wtedy, jeśli strona nie załaduje się całkowicie, nadal potencjalnie będziesz mieć pewną funkcjonalność. Połowy strony pracy są gorsze niż pełne popiersia. W najlepszym wypadku powodują, że więcej odwiedzających witrynę słusznie zakłada, że jesteś niekompetentny, zanim się o tym dowiesz, niż jeśli strona, której dotyczy błąd, jest po prostu odsyłana do strony z błędem po niepowodzeniu własnej weryfikacji, a następnie automatycznej wiadomości e-mail na adres ktoś, kto może coś z tym zrobić.
Próba dostarczenia funkcji 2010 w przeglądarce 1999, kiedy można po prostu dostarczyć stronę o niższej technologii, jest kolejnym przykładem kompromitacji w projektowaniu. Wykorzystane możliwości i pieniądze, które widziałem zmarnowane na czas programisty spędzony na obejściach związanych z błędami, aby na przykład zaokrąglić rogi elementu unoszącego się na przykład nad gradientowym tłem! @ # $ Ing, całkowicie mnie zaskoczyły. I po co? Dostarczanie stron o wyższej technologii, które działają słabo do sprawdzonych technofobów, ograniczając jednocześnie możliwości wyboru w wyższych przeglądarkach.
Aby był to właściwy wybór, solidna obsługa danych wejściowych powinna zawsze ułatwiać życie po obu stronach problemu, zarówno w krótkim, jak i długim okresie IMO.
źródło
Nigdy nie zawiedź cicho . Poza tym próba odgadnięcia, czego chciał użytkownik interfejsu API / biblioteki, nie wydaje się złym pomysłem. Nie poszedłbym za tym; mając ścisłe wymagania, może ujawniać błędy w kodzie wywołującym i / lub błędne interpretacje dotyczące twojego API / biblioteki.
Ponadto, jak już wspomniano, zależy to od tego, jak trudno odgadnąć, czego oczekuje użytkownik. Jeśli jest to bardzo łatwe, masz dwa przypadki:
W każdym razie, że nie jest to w 100% oczywiste i deterministyczne, że jedno wejście należy przekonwertować na inne, nie należy wykonywać konwersji z wielu już wspomnianych powodów (łamanie zgodności przy refaktoryzacji, najmniejsze zdziwienie użytkowników).
W kontaktach z użytkownikiem końcowym próba naprawienia jego danych wejściowych / zgadywania jest bardzo mile widziana. Jest on oczekiwać , aby wprowadzić nieprawidłowe informacje; ten przypadek jest całkowicie wyjątkowy. Jednak inny programista nie jest prostym nietechnicznym użytkownikiem. Ma specjalistyczną wiedzę, aby zrozumieć błąd, a błąd może mieć znaczenie / być dla niego korzystny. Dlatego zgadzam się z tobą w sprawie projektowania ścisłych interfejsów API, podczas gdy - oczywiście - ścisłości towarzyszy jasność i prostota.
Poleciłbym przeczytać to moje pytanie dotyczące podobnej sprawy.
źródło