Разве «соглашение над конфигурацией» не нарушает основные принципы программирования?

51

Я смотрел на инфраструктуру WPF MVVM Caliburn.Micro и читал, что многие стандартные вещи основаны на соглашениях об именах .

Например, автоматическое связывание свойств в представлении со свойствами в ViewModel. Хотя это кажется удобным (удаляет некоторый шаблонный код), моя первая реакция на инстинкт заключается в том, что это не совсем очевидно для нового программиста, который будет читать этот код. Другими словами, функциональность приложения не полностью объясняется его собственным кодом, но также и документацией платформы.

РЕДАКТИРОВАТЬ:

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

Мой вопрос:

Является ли соглашение о конфигурации правильным способом упрощения вещей или это нарушает некоторые принципы программирования (и если да, то какие)?

Geerten
источник
8
Большинство подходов / принципов в некоторой степени нарушают некоторые другие подходы / принципы. Это в основном вопрос приоритетов и компромиссов.
Йоахим Зауэр
1
Правда, но я нахожу разницу, изложенную в моем вопросе, немного странной, и поэтому меня интересуют конкретные компромиссы и, возможно, нарушение принципов при использовании соглашения о конфигурации.
Гертен
Концепция прослеживаемости программного обеспечения актуальна здесь. Программисты полагаются на такие инструменты, как grep, но им нужны более совершенные инструменты для отслеживания использования сгенерированного кода. Например, инструменты должны сделать более явным, что класс css "user-id" связан с генерируемым методом getUserId () и столбцом таблицы user_id.
Макнейл

Ответы:

49

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

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

Согласование и настройка баланса - сложная задача. Слишком большое соглашение может привести к путанице в коде (например, взять неявные переменные Perl). Слишком большая свобода со стороны программиста может затруднить понимание систем, поскольку знания, полученные из одной системы, редко полезны при изучении другой.

Хороший пример того, где соглашение помогает программисту, при написании плагинов Eclipse. Когда я смотрю на плагин, который я никогда не видел, я сразу узнаю о нем много вещей. Список зависимостей находится в файле MANIFEST.MF, точки расширения - в файле plugin.xml, исходный код находится в разделе «src» и т. Д. Если бы все это определял программист, каждый плагин Eclipse был бы другим, и навигация по коду была бы намного более сложной.

JesperE
источник
4
+1: разработка программного обеспечения достаточно сложна, как она есть. Если вы можете избежать сложности в вещах, которые вы контролируете, сделайте это. Сохраните сложность для мест, которые вам абсолютно необходимы.
scrwtp
1
Спасибо за четкое объяснение разницы и баланса.
Гертен
3
«Если идентификатор в Java начинается с заглавной буквы, это тип». - зависит ли тип от контекста синтаксиса, а не от шаблона именования, соглашения об именах Java не влияют на «конфигурацию компиляции». Вы уверены, что это верный пример? Последний пример также неверен - он касается «соглашений о конфигурации», а не «соглашения о конфигурации». Вы говорите правильные вещи, но они не имеют ничего общего с принципом subj.
День
4
Не переоценивайте примеры, они просто примеры. Первый - это пример соглашения, последний - пример, где соглашение - это хорошо. Пример Perl - это пример, когда слишком много соглашений (последствий) являются плохой вещью (IMO, я должен добавить).
JesperE
1
Я ненавижу, когда соглашение о конфигурации становится соглашением без конфигурации ... в последнем случае вы, как правило, попадаете в ловушку кодовой базы, что может быть трудно интегрировать с другими инструментами.
Энди
77

Дали +1 к @JesperE и хотели бы кое-что добавить:

это нарушает некоторые принципы программирования

Да, «соглашение о конфигурации» нарушает принцип «явное лучше, чем неявное» (посмотрите, например, «Zen-Of-Python» ).

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

Док Браун
источник
4
Это самый прямой ответ на вопрос!
Иоахим Зауэр
Это фактический правильный ответ среди двух наиболее проголосовавших.
Ден
+1 за «явный лучше, чем неявный»
Джастин Омс
12
Моя любимая часть этого ответа состоит в том, что он неявно подчеркивает реальность, чем принципы хорошей разработки программного обеспечения, часто находящиеся в напряжении друг с другом. Инжиниринг - это балансировка напряжений в соответствии с вашим конкретным контекстом и применением.
Крис Кричо,
Хороший ответ. Чтобы расширить комментарий @Chris Krycho, хорошая вещь о стандартах или принципах программного обеспечения состоит в том, что у вас есть так много выбора. :-)
user949300
9

Некоторые из «соглашений о конфигурации» сводятся к разумным значениям по умолчанию. Вам нужно только настроить что-то, чтобы использовать это в нестандартных целях. Я должен сравнить Struts с Rails здесь. В Rails вы должны поместить ваши «действия / экраны» в папку, и тогда они просто будут работать. В Struts вам все еще нужно поместить их в папку, но вы также должны придумать имя действия И файл JSP И имя формы И бин формы И указать, как эти три вещи работают вместе в Struts-config. xml И укажите, что форма принадлежит запросу (RESTful). Если этого недостаточно, отображение формы / формы bean-компонента имеет свой собственный раздел в Struts-config, который затем сопоставляется независимо с разделом действия в том же файле, и все это опирается на рукописные строки в файле JSP для работы должным образом. Для каждого экрана это как минимум 6 вещей, которые вам не нужно делать, и столько же возможностей сделать ошибку. Я думаю, что вы можете установить большинство или все эти вещи вручную в Rails, если вам нужно, но 2/3 времени разработки Struts занимает создание и поддержание ненужных уровней сложности.

Справедливости ради, Struts 1 был разработан, когда люди портировали приложения между рабочим столом и сетью. Гибкость, которую запустил Struts, делает его подходящим для всего, что делает Rails, плюс все, что может понадобиться настольному приложению. К сожалению, гора конфигурации, которая обеспечивает такую ​​гибкость, является огромным препятствием для тех, кому просто нужно написать веб-приложение или просто настольное приложение.

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

Я не могу себе представить, что наличие разумных значений по умолчанию нарушает любые теоретические принципы расширяемости и модульности. Программист на Ruby / Rails скорее бросил бы в глаза горячий покер, чем переключился бы на такую ​​инфраструктуру, как Struts 1, где все конфигурации были сделаны явно в нескольких файлах XML. Я не спорю Rails против Struts IN GENERAL, но это соглашение может стать огромным выигрышем в производительности. Эти две технологии - самое экстремальное сравнение в реальном мире, с которым я сталкивался.

Если вы вообще работаете в Java, прочитайте статью Джошуа Блоха «Эффективная Java», пункт 2: «Рассмотрите Builder, когда сталкиваетесь со многими параметрами конструктора», стр. 11-16. Для большинства целей некоторые параметры (конфигурация) являются обязательными, а некоторые - необязательными. Основная идея состоит в том, чтобы требовать только необходимую конфигурацию и заставлять пользователя (который может быть другой программой) указывать дополнительные параметры по мере необходимости. Я убрал кучу кода с этим шаблоном месяц назад, и он положительно сверкает.

GlenPeterson
источник
7

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

Функциональность приложения, которое использует платформу, всегда зависит от платформы, соглашение о конфигурации не имеет значения в этом отношении.

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

Например, давайте предположим, что в некоторой структуре A событие FooBarвызывает вызов handleFooBar. В другом фреймворке B это соотношение настраивается где-то в XML-файле.

Итак, в А это просто

handleFooBar() {
   ...
}

и если вы неправильно написали FooBar, он будет вызываться всякий раз, когда происходит FooBar.

В Б это опять

handleFooBar() {
   ...
}

но и

<eventconfiguration>
  <event>
    <type>FooBar</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

С сотнями вещей, которые можно настроить таким образом, слишком легко случайно создать тонкую ошибку, такую ​​как

<eventconfiguration>
  <event>
    <type>BarFoo</type>
    <handler>handleFooBar</handler>
  </event>
</eventconfiguration>

потому что после копирования мы только изменились, <type>но забыли изменить <handler>.

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

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

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

rai.skumar
источник
2
Использование соглашений не имеет ничего общего с единственной ответственностью. Я мог бы использовать соглашение и делать в нем 100 вещей.
Суамер