Почему «откровенность» считается хорошей вещью? - PullRequest
14 голосов
/ 18 декабря 2009

Я часто слышу, как люди хвалят языки, структуры, конструкции и т. Д. За то, что они "явные". Я пытаюсь понять эту логику. Цель языка, структуры и т. Д. - скрыть сложность. Если он заставляет вас явно указывать все виды деталей, то он не скрывает много сложностей, а только перемещает их. Что такого замечательного в явности и как вы делаете язык / инфраструктуру / API «явным», в то же время заставляя его служить цели сокрытия сложности?

Ответы [ 13 ]

30 голосов
/ 18 декабря 2009

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

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

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

Пример: Однажды я удалил около 90 строк кода из серии из дюжины кодов за страницами; код доступа к данным, бизнес-логика и т. д., которые там не принадлежали. Я переместил их на базовые страницы и ключевой бизнес-объект. Это было хорошо (инкапсуляция, разделение задач, организация кода, развязка и т. Д.).

Затем я взволнованно осознал, что могу удалить последнюю строку кода со многих из этих страниц, переместив ее на базовую страницу. Это была строка, которая взяла параметр из URL и передала его бизнес-объекту. Хорошо право? Ну, нет, это было плохо прятался ). Эта логика принадлежала здесь, хотя она была почти одинаковой строкой на каждой странице. Он связал намерение пользовательского интерфейса с бизнес-объектом. Это должно быть явное . В противном случае я прятался, не заключая в капсулу. С этой строкой кто-то, глядя на эту страницу, будет знать, что эта страница делает и почему; без этого было бы больно определять, что происходит.

15 голосов
/ 18 декабря 2009

Я считаю, что явное относится к знанию того, что он делает, когда вы его используете. Это отличается от точного знания того, как это делается, что является сложной частью.

8 голосов
/ 18 декабря 2009

Это не так уж и хорошо, что явное хорошо (конечно, тесно связанное многословное плохо), а то, что когда неявное идет не так, трудно скажите, что WTF продолжается.

Взламывайте C ++ в течение десяти или двух лет, и вы точно поймете, что я имею в виду.

7 голосов
/ 18 декабря 2009

Речь идет о выражении намерений. Читатель не может сказать, был ли оставлен дефолт по ошибке или умышленно. Быть явным убирает это сомнение.

6 голосов
/ 18 декабря 2009

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

4 голосов
/ 18 декабря 2009

Быть явным против неявного - это все, что вы скрываете, и что вы показываете.

В идеале вы раскрываете понятия, которые интересуют или интересуют пользователя (независимо от того, хотят они этого или нет).

Преимущество откровенности в том, что легче отследить и выяснить, что происходит, особенно в случае сбоя. Например, если я хочу вести журнал, у меня может быть API, который требует явной инициализации с каталогом для журнала. Или я могу использовать значение по умолчанию.

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

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

Часто неявное поведение является результатом "самоконфигурирования" объектов, которые смотрят на свое окружение и пытаются угадать правильное поведение. Я бы вообще избегал этого паттерна.

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

4 голосов
/ 18 декабря 2009

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

Подумайте, как трудно понять Perl-код, который в значительной степени опирается на сокращения, для людей, которые не знают Perl.

3 голосов
/ 18 декабря 2009

Каркасы и т. Д. Могут быть как явными, так и скрывать сложность, предлагая правильные абстракции для выполняемой работы.

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

Сложность сокрытия не эквивалентна неявности. Неявность привела бы к тому, что код, понятный только тому, кто его написал, пытался понять, что происходит под капотом, в этом случае сродни реверс-инжинирингу.

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

Явный код является поддерживаемым, неявный код - нет - это ссылка на предоставление правильных комментариев и осторожный выбор идентификаторов.

2 голосов
/ 18 декабря 2009

Хорошая абстракция не скрывает сложностей, она принимает решения, которые лучше оставить на усмотрение компилятора.

Рассмотрим сборку мусора. Сложности освобождения ресурсов делегируются сборщику мусора, который (предположительно) более квалифицирован для принятия решения, чем вы, программист. Оно не только снимает решение с ваших рук, но и принимает лучшее решение, чем вы сами.

Явность (иногда) хороша, потому что она делает так, что некоторые решения, которые в некоторых случаях лучше оставить программисту, не принимаются автоматически менее квалифицированным агентом. Хороший пример - когда вы объявляете тип данных с плавающей запятой на языке c-type и инициализируете его целым числом:

double i = 5.0;

если вместо этого вы объявите его как

var i = 5;

компилятор по праву предположит, что вы хотите использовать int, а последующие операции будут усечены.

2 голосов
/ 18 декабря 2009

Ясность желательна в контексте разъяснения читателю вашего кода того, что вы намеревались сделать.

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

например. Это не очень ясно:

while (condition);

int MyFunction()

bool isActive;         // In C# we know this is initialised to 0 (false)

a = b??c;

double a = 5;

double angle = 1.57;

но это:

while (condition)
    /* this loop does nothing but wait */ ;

private int MyFunction()

int isActive = false;  // Now you know I really meant this to default to false

if (b != null) a = b; else a = c;

double a = 5.0;

double angleDegrees = 1.57;

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

...