Почему "очевидность" считается хорошей?

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

Ответы

Ответ 1

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

Hack С++ в течение десятилетия или двух, и вы точно поймете, что я имею в виду.

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

Речь идет о выражении намерений. Читатель не может определить, по умолчанию ли по умолчанию или по дизайну. Явное устранение этих сомнений.

Ответ 5

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

Ответ 6

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

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

Ответ 7

Явное vs. неявное - это все, что вы скрываете, и то, что вы показываете.

В идеале вы раскрываете концепции, которые либо заботятся о пользователях, либо должны заботиться о них (хотят они или нет).

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

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

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

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

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

Ответ 8

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

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

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

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

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

Ответ 9

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

Например, С++ имеет ключевое слово const для переменных, значения которых никогда не должны меняться. Если программа пытается изменить эти переменные, компилятор может указать, что код, вероятно, неверен.

Ответ 10

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

Есть много примеров, но все это не оставляет никаких сомнений в ваших намерениях.

например. Они не очень явны:

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;

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

Ответ 11

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

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

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

double i = 5.0;

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

var i = 5;

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

Ответ 12

В некоторых случаях противоположность - "магия" - как в "тогда происходит чудо" .

Когда разработчик, читающий код, пытающийся понять или отладить, что происходит, объяснение может быть добродетелью.

Ответ 13

Цель фреймворков, движущихся вокруг, - удалить дублирование кода и упростить редактирование кусков, не нарушая все это. Когда у вас есть только один способ сделать что-то, например, SUM (x, y); Мы точно знаем, что это будет делать, нет причин когда-либо переписывать его, и, если хотите, но это маловероятно. Противоположность этому - языки программирования, такие как .NET, которые предоставляют очень сложные функции, которые вам часто придется переписывать, если вы ничего не делаете, кроме простого простого примера.