Будьте либеральными в том, что вы принимаете ... или нет?

softwareengineering.stackexchange https://softwareengineering.stackexchange.com/questions/12401

  •  16-10-2019
  •  | 
  •  

Вопрос

Отказ от ответственности: этот вопрос субъективен, но я бы предпочел получить ответы, подкрепленные фактами и/или рефлексиями

Я думаю, что все знают о Принцип надежности, обычно суммируется законом Постеля:

Будьте консервативны в том, что вы отправляете; Будьте либеральными в том, что вы принимаете.

Я бы согласился с тем, что для проектирования широко распространенного протокола связи это может иметь смысл (с целью разрешения легкого расширения), однако я всегда думал, что его применение к HTML / CSS было полным сбоем, каждый браузер реализует свой собственный тихий настройка Обнаружение / поведение, что делает почти невозможным получить последовательный рендеринг в нескольких браузерах.

Я заметил, что там RFC протокола TCP считает «молчаливую неудачу» приемлемой, если не указано иное ... что является интересным поведением, если не сказать больше.

Существуют и другие примеры применения этого принципа на протяжении всей торговли программным обеспечением, которые регулярно появляются, потому что они укушены разработчиков, с верхней части моей головы:

  • JavaScript полуколона вставка
  • C (Silent) Строительные преобразования (которые не были бы так плохо, если бы они не усекнули ...)

И есть инструменты, помогающие реализовать «умное» поведение:

Однако я считаю, что этот подход, хотя он может быть полезен при работе с нетехническими пользователями или помогать пользователям в процессе восстановления ошибок, имеет некоторые недостатки при применении к дизайну библиотеки/класса интерфейса:

  • несколько субъективно, предполагает ли алгоритм «правильно», и, таким образом, он может пойти против Принцип наименьшего удивления
  • Это делает реализацию более сложной, что больше шансов ввести ошибки (нарушение Ягни ?)
  • Это делает поведение более восприимчивым к изменениям, так как любая модификация рутины «угадать» может нарушить старые программы, почти исключая возможности рефакторинга ... с самого начала!

И это то, что привело меня к следующему вопросу:

При разработке интерфейса (библиотека, класс, сообщение) вы склоняетесь к принципу надежности или нет?

Я сам, как правило, довольно строг, используя обширную проверку ввода на своих интерфейсах, и мне было интересно, если я, возможно, слишком строг.

Это было полезно?

Решение

я бы сказал надежность, когда это не вводит неясности.

Например: при разборе списка запятой отдельно, независимо от того, есть ли место до/после того, как запятая не меняет семантическое значение.

При анализе строкости GUID он должен принять любое количество общих форматов (с тире или без него, с окружающими вьющимися скобками).

Большинство языков программирования надежны с использованием белого пространства. В частности, везде, где это не влияет на значение кода. Даже в Python, где WhiteSpace актуален, он все еще гибкий, когда вы находитесь в списке или в словаре.

Я определенно согласен с тем, что если что -то можно интерпретировать несколько способов или если на 100% ясно, что означает, что слишком большая надежность может оказаться болью, но есть много места для надежности, не будучи неоднозначными.

Другие советы

Точно нет. Такие методы, как защитное программирование неясно Ошибки, что делает их внешний вид менее вероятной и случайнее, что делает их обнаружение труднее, что затрудняет их изоляцию.

Чрезвычайно недостаток Написание солидного кода Был огромным, неоднократно подчеркивая необходимость и методы, чтобы сделать ошибки такими, как ввести или скрыть. Благодаря применению его принципов, таких как «Устранение случайного поведения. Закажите ошибки воспроизводимых». и «всегда ищите и устраняйте недостатки в ваших интерфейсах». Разработчики значительно улучшат качество своего программного обеспечения, устраняя двусмысленность и неконтролируемые побочные эффекты, которые отвечают за большое количество ошибок.

Изменение надежности приводит к тому, что вы угадаете, чего хотел пользователь, что в порядке, пока вы не пойдете неправильно. Также требуется совершенно ошибочная вера, что ваши клиенты не злоупотребляют вашим доверием и не создают случайную тампу, которая просто работает, но вы не сможете поддержать в версии 2.

Переупреждение правильности приводит к тому, что вы отрицаете, что своим клиентам право совершать незначительные ошибки, что в порядке, пока они не пожалеются, что их вещи прекрасно работают на продукте вашего конкурента, и сообщите вам, что вы можете сделать со своим стандартом на 5000 страниц, который имеет слово «Проект» по -прежнему нацарапался на обложке в каранданом, и по крайней мере 3 эксперта утверждают, что в корне ошибочно, и еще 200 честных экспертов говорят, что они не до конца понимают.

Моим личным решением всегда было снижение. Вы поддерживаете их, но говорите им, что они делают неправильно, и (если возможно) самый простой путь к правильности. Таким образом, когда вы выключаете ошибку с 10 лет спустя 10 лет, у вас, по крайней мере, есть бумажный след, чтобы утверждать, что «мы предупредили вас, что это может произойти».

К сожалению, так называемый «принцип надежности» не приводит к надежности. Возьмите HTML в качестве примера. Много неприятностей, слез, траты времени и энергии можно было избежать, если бы браузеры строго проанализировали HTML с самого начала, а не пытались угадать смысл уродственного содержания.

Браузер должен был просто отобразить сообщение об ошибке вместо того, чтобы пытаться исправить его под обложками. Это заставило бы всех бункеров исправить свой беспорядок.

Я разделяю интерфейсы на несколько групп (добавьте больше, если хотите):

  1. Те, кто находится под вашим контролем, должны быть строгими (обычно классы)
  2. Библиотечные API, которые также должны быть строгими, но рекомендуется дополнительная проверка
  3. Общественные интерфейсы, которые должны обрабатывать все виды злоупотреблений, которые возникают (обычно протоколы, входы пользователей и т. Д.). Здесь надежность ввода действительно окупается, вы не можете ожидать, что все собираются исправить свои вещи. И помните, что для пользователя это будет ваша вина, если приложение не сработает, а не сторона, которая отправила немного плохо форматированного дерьма.

Вывод всегда должен быть строгим.

Я думаю, что HTML и World Wide Web предоставили широкомасштабную реальную тест на принцип надежности и показали, что он является огромным провалом. Он несет непосредственную ответственность за запутанную беспорядка конкурирующего HTML почти Standard, что делает жизнь несчастной для веб-разработчиков (и их пользователей) и ухудшается с каждым новым релизом Internet Explorer.

Мы знали с 1950 -х годов, как правильно проверить код. Запустите его через строгий анализатор, и если что -то не является синтаксически правильным, добавьте ошибку и прервите. Не проходите, не собирайте 200 долларов, и ради любви ко всему, что является бинарным Не позволяйте какой -либо компьютерной программе пытаться прочитать разум кодера, если он совершил ошибку!

HTML и JavaScript показали нам именно то, что происходит, когда эти принципы игнорируются. Лучший курс действия - учиться на своих ошибках и не повторять их.

В качестве контрапункта на примере Мейсона, мой опыт работы с Протокол инициации сеанса было то, что в то время как разные стеки будут интерпретировать соответствующие RFC по -разному (и я подозреваю, что это происходит с каждый Стандартный когда -либо написан), будучи (умеренно) либеральным в том, что вы принимаете, означает, что вы действительно можете совершать звонки между двумя устройствами. Поскольку эти устройства являются обычными физическими вещами, в отличие от кусков программного обеспечения на рабочем столе, вы просто должны быть либеральными в том, что вы принимаете, или ваш телефон не может позвонить другому телефону конкретной марки. Это не делает ваш телефон хорошо выглядеть!

Но если вы пишете библиотеку, у вас, вероятно, нет проблемы с тем, чтобы несколько сторон интерпретировали общий стандарт взаимозаведитеми. В этом случае я бы сказал, что будь строгим в том, что вы принимаете, потому что это устраняет неясности.

Файл жаргона также имеет страшная история на «угадании» намерения пользователя.

Вы правы, правило применяется к протоколам, а не к программированию. Если вы делаете опечатку во время программирования, вы получите ошибку, как только компилируете (или запустите, если вы один из этих динамических типов). Нечего получить, позволив компьютеру угадать вас. В отличие от обычных людей, мы инженеры и способны точно сказать, что я имею в виду. ;)

Итак, при разработке API я бы сказал не Следуйте принципу надежности. Если разработчик совершает ошибку, он должен сразу узнать об этом. Конечно, если ваш API использует данные из внешнего источника, например, файл, вы должны быть сниженными. Пользователь вашей библиотеки должен узнать о его/ее собственных ошибках, но не кого -то еще.

Кроме того, я бы предположил, что в протоколе TCP разрешен «молчаливый неудача», потому что в противном случае, если бы люди бросали в вас узорформированные пакеты, вы были бы засыпаны сообщениями об ошибках. Это простая защита DOS прямо здесь.

ИМО, надежность является одной из сторон дизайна, а не принципа «предпочтение». Как отмечали многие, ничто не воняет, как продувать четыре часа, пытаясь выяснить, где ваш JS пошел не так, чтобы обнаружить, что настоящая проблема заключалась в том, что только один браузер сделал правильную вещь со строгими XHTML. Это позволило странице пройти на куски, когда какая -то часть обслуживаемого HTML была полной катастрофой.

С другой стороны, кто хочет искать документацию для метода, который принимает 20 аргументов и настаивает на том, что они находятся в том же порядке с пустыми или нулевыми держателями места для тех, кого вы хотите пропустить? Не менее ужасным способом справиться с этим методом было бы проверить каждый ARG и попытаться угадать, какой из них был для того, что основано на относительных позициях и типах, а затем молча не терпит неудачу или попытаться «делать» с бессмысленными ARG.

Или вы можете запекать гибкость в процессе, передавая список литерала/словаря/клавиш-значений и обработать существование каждого ARG, когда вы добираетесь до него. Для очень незначительного компромисса Perf, это торт и съесть его слишком сценарий.

Перегрузка ARGs интеллектуальными и согласованными с интерфейсом-это разумный способ быть надежным. Таким образом, выпечка избыточности в систему, в которой предполагается, что доставка пакетов регулярно не будет осуществляться в чрезвычайно сложной сети, принадлежащей и управляемой всеми в новой технологии с широким спектром потенциальных средств для передачи.

Однако терпимое устранение сбоя, особенно в рамках системы, которую вы контролируете, никогда не является хорошим компромиссом. Например, мне пришлось взять передышку, чтобы избежать того, чтобы бросить фиксацию в другой вопрос о том, чтобы поставить JS на вершину или внизу страницы. Несколько человек настаивали на том, что лучше поставить JS наверх, потому что тогда, если страница не смогла полностью загрузить, вы все равно потенциально получили бы некоторую функциональность. Получатые страницы хуже, чем полные бюсты. В лучшем случае они приводят к тому, что больше посетителей вашего сайта справедливо предполагают, что вы некомпетентны, прежде чем вы узнаете об этом, чем если бы страница разорванной подключена к странице ошибки при сбоне собственной проверки проверки, за которой следует автоматизированная электронная почта, чтобы Кто -то, кто может что -то с этим сделать. Будете ли вы чувствовать себя комфортно, передав информацию о своей кредитной карте на сайт, который постоянно был наполовину зарегистрирован?

Попытка обеспечить функциональность 2010 года в браузере 1999 года, когда вы можете просто предоставить более низкую техническую страницу, является еще одним примером безрассудного компромисса дизайна. Возможности взорвались, и деньги, которые я видел, потратил на то, что разработчик, потраченное на обходные пути, только чтобы получить закругленные углы на элементе, зависящий над фонами градиента!@$ Ing, полностью поразили меня. И для чего? Для доставки более высоких технических страниц, которые плохо работают до проверенных технофобов, ограничивая при этом выбор в браузерах с более высоким уровнем конец.

Для того, чтобы он был правильным выбором, выбор для выполнения ввода надежным образом всегда должен облегчить жизнь по обе стороны проблемы, в краткосрочной и долгосрочной IMO.

Никогда не терпитесь молча. Анкет Кроме того, попытка угадать, что хотел пользователь API/библиотеки, не звучит как плохая идея. Я бы не следовал за этим, хотя; Наличие строгого требования, может раскрыть ошибки в вызывающем коде и/или неверные истолкования о вашем API/библиотеке.

Кроме того, как уже было указано, это зависит от того, насколько сложно угадать, что ожидает пользователь. Если это очень легко, то у вас есть два случая:

  1. Ваша библиотека должна быть разработана немного по -другому (переименовать некоторую функцию или разделить ее на две части), чтобы пользователь мог ожидать того, что вы на самом деле предоставите.
  2. Если вы считаете, что ваша библиотека разработана должным образом, что означает четкое / простое именование, то вы можете попытаться сделать вывод, что предполагал пользователь.

В любом случае, что не является на 100% очевидным и детерминированным, что один вход должен быть преобразован в другой, вы не должны делать конверсии, по ряду уже упомянутых причин (нарушение совместимости при рефакторинге, наименьшее удивление пользователей).

При работе с конечным пользователем, попытка исправить их ввод/догадку очень приветствуется. Он ожидал ввести неверную информацию; Этот случай совершенно неожиданно. Другой разработчик, однако, не простой не технический пользователь. У него есть опыт, чтобы понять ошибку, и ошибка может иметь значение/быть полезной для него. Таким образом, я согласен с вами в разработке строгих API, в то время как, конечно, строгость сопровождается ясностью и простотой.

Я бы порекомендовал вам прочитать Этот мой вопрос, аналогичного случая.

Лицензировано под: CC-BY-SA с атрибуция
scroll top