Как разделение кода и данных стало практикой?

29

Пожалуйста, внимательно прочитайте вопрос: он спрашивает, как , а не почему .

Недавно я наткнулся на этот ответ , который предлагает использовать базу данных для хранения неизменяемых данных:

Похоже, многие из магических чисел, которые вы описываете - особенно если они зависят от части - на самом деле являются данными, а не кодом. [...] Это может означать базу данных типа SQL или просто форматированный текстовый файл.

Мне кажется, что если у вас есть данные, которые являются частью того, что делает ваша программа, то вам нужно поместить их в программу . Например, если функция вашей программы заключается в подсчете гласных звуков, что плохого в том, чтобы vowels = "aeiou"в них присутствовать? В конце концов, большинство языков имеют структуры данных, предназначенные именно для этого использования. Почему вы хотите разделить данные , поместив их в «форматированный текстовый файл», как предложено выше? Почему бы просто не сделать этот текстовый файл отформатированным на выбранном вами языке программирования? Теперь это база данных? Или это код?

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

Возьмем, к примеру, эту статью: Проблема с отделением данных от кода Puppet . Проблема ? Какая проблема? Если Puppet - это язык для описания моей инфраструктуры, почему он не может также описать, что сервер имен - это 8.8.8.8? Мне кажется, что проблема не в том, что код и данные смешаны 1, а в том, что в Puppet не хватает достаточно богатых структур данных и способов взаимодействия с другими вещами.

Я считаю этот сдвиг тревожным. Объектно-ориентированное программирование гласило: «Мы хотим сколь угодно богатые структуры данных», и поэтому наделило структуры данных возможностями кода. В результате вы получаете инкапсуляцию и абстракцию. Даже базы данных SQL имеют хранимые процедуры. Когда вы изолируете данные в YAML или текстовые файлы или тупые базы данных, как будто вы удаляете опухоль из кода, вы теряете все это.

Кто-нибудь может объяснить, как появилась эта практика отделения данных от кода и куда она идет? Может ли кто-нибудь ссылаться на публикации светил или предоставить некоторые соответствующие данные, которые демонстрируют «отдельный код из данных» в качестве новой заповеди и иллюстрируют ее происхождение?

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

Фил Фрост
источник
5
Не стесняйтесь хоронить все html & css на вашем языке.
JeffO
3
Я думаю, что автор цитаты имел в виду, что магические числа не являются неизменными.
Питер Б
4
Нет ничего плохого в жестком кодировании гласных. Если ваше приложение будет когда-либо использоваться только для подсчета гласных на английском языке.
Майкл Паукуонис
3
Большая техническая причина для разделения кода и данных состоит в том, что нет необходимости перекомпилировать код при изменении данных. Поэтому я бы спросил, применимо ли это в той же степени к языкам сценариев.
user16764
1
@MichaelPaulukonis: И поместить его в базу данных - фальшивое решение. Нужны ли изменения для голландского? Ноль (даже не изменение БД). Нужны ли изменения для французского / немецкого? По крайней мере, поддержка ISO-8859-1. (Больше чем БД). Нужны ли изменения для греческого / русского? Поддержка Unicode (больше, чем БД). На самом деле, я не могу придумать ни одного языка, в котором эта БД поможет.
MSalters

Ответы:

22

Есть много веских причин отделять данные от кода, а некоторые - нет. На ум приходят следующие.

Своевременность. Когда известно значение данных? Это происходит во время написания кода, когда он компилируется, связывается, освобождается, лицензируется, конфигурируется, запускается или работает. Например, количество дней в неделе (7) известно рано, но обменный курс USD / AUD будет известен довольно поздно.

Состав. Является ли это единым временем данных, установленным в соответствии с одним соображением, или оно может быть унаследовано или являться частью большей коллекции элементов? Такие языки, как YAML и JSON, позволяют комбинировать значения из нескольких источников. Возможно, некоторые вещи, которые изначально кажутся неизменяемыми, лучше сделать доступными в качестве свойств в диспетчере конфигурации.

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

Разделение проблем. Получение алгоритмов для правильной работы лучше всего отделить от рассмотрения того, какие значения данных использовать. Данные нужны для тестирования алгоритмов, а не для их включения. Смотрите также http://c2.com/cgi/wiki?ZeroOneInfinityRule .

В ответ на ваш вопрос это не новость. Основные принципы не изменились за более чем 30 лет, и о них неоднократно писали за это время. Я не могу вспомнить каких - либо серьезных публикаций по данной теме , поскольку это , как правило , не считается спорным, просто что - то , чтобы объяснить новичкам. Здесь есть немного больше: http://c2.com/cgi/wiki?SeparationOfDataAndCode .

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

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

david.pfx
источник
2
Не могли бы вы рассказать об истории и направлениях этой практики? Если бы все высказали эти соображения, я бы не задавал вопрос. Суть вопроса заключается в том, что люди не заботятся о том, куда должны поступать их данные (скомпилированные константы, внешние базы данных, YAML ...), а скорее думают только: «ПЛОХО КОДА И СМЕШАННЫХ ДАННЫХ! Почему или когда это стало вещью?
Фил Фрост
Это не часть моего опыта, поэтому я не могу вам сказать. Я добавил пару пунктов к своему ответу.
david.pfx
Я думаю, что «наплыв молодежи» - правильное объяснение, но я не могу согласиться с этим, потому что я хотел бы услышать от некоторых из этих молодых людей, чтобы узнать, откуда у них появилась идея. Ясно, что они получили часть «отдельный код и данные», но я не думаю, что они получили остальное. Они прочитали это в сообщении в блоге? Книга? Где и когда?
Фил Фрост
Вы всегда будете получать "_____ ПЛОХОЙ! ХАЛК SMASH!" - это не значит, что это правда. Часто такого рода вещи (например, "GOTO" ПЛОХОЙ! ХАЛК SMASH! ") Преподаются новичкам, не обучая их, почему или каковы исключения.
AMADANON Inc.
Localityтакже работает в обратном порядке: мы получили систему типа плагинов из-за пользовательских требований для разных клиентов и через несколько лет проб и ошибок научились хранить их константы (даже таблицы, в виде списков различий) вне базы данных и в коде. И потому, что использование его где-либо, кроме этого «плагина», некорректно, и потому, что изменения автоматически версионируются, когда происходят изменения.
Изката
8

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

разрешений

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

  • Только разработчики могут редактировать данные. Это плохо - ввод данных - это не то, что требует навыков и знаний разработчика.

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

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

редактирование

Итак, что касается того, кто может редактировать данные, лучше хранить их отдельно. Как насчет того, как они будут редактировать данные? Если у вас есть много данных, набирать их вручную утомительно и из-за ошибок. Наличие некоторого пользовательского интерфейса для этого намного лучше! Даже если вам все равно придется печатать все, вам не нужно будет набирать шаблон формата, поэтому у вас будет меньше шансов испортить формат и испортить весь файл!

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

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

пересчет

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

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

поиск

У вас есть тонны данных - вполне естественно, что вы захотите найти их.

  • Если вы храните его в базе данных - вы можете использовать язык запросов к базе данных.

  • Если вы храните его в файле XML - вы можете использовать XPath.

  • Если вы храните его в формате JSON / YAML - вы можете загрузить его на REPL вашего любимого языка сценариев и выполнить поиск.

  • Даже если вы храните его в простом старом текстовом файле, так как он имеет структуру, которую ваша программа может распознать, вы можете использовать grep / sed / awk для его поиска.

Хотя верно и то, что вы можете также выполнять grep / sed / awk через жестко закодированные данные в исходном файле, это не так хорошо работает, так как ваш запрос может совпадать с другими, не связанными строками или пропущенными строками, которые были написаны по-другому, потому что синтаксис представления данных языка программирования позволяет это.

Существуют инструменты для поиска по коду, но они хороши для поиска объявлений, а не жестко закодированных данных.

Что, как говорится...

Очень важно различать данные и код. То, что что-то написано как код, не означает, что это не могут быть данные. И то, что что-то написано с представлением данных, не означает, что это на самом деле не код.

У меня был класс, когда у нас были очень строгие правила о «магических числах» - у нас не могло быть никаких чисел в нашем коде. Это означает, что мы должны были сделать что-то вроде:

#define THE_NUMBER_ZERO 0
//....
for(int i=THE_NUMBER_ZERO;i<cout;++i){
//....

что просто смешно! Да, 0технически это «данные», но это такая же часть кода, как и остальная часть forцикла! Поэтому, даже если мы можем представить его как данные и отделить его от кода, это не значит, что мы должны это делать . Не потому, что мы хотим оставить данные внутри кода, а потому, что на самом деле это не данные - не больше, чем остальная часть кода, которая также скомпилирована в единицы и нули ...

Идан Арье
источник
7

Я думаю, что происходит некоторая путаница. Вы смешиваете две вещи: «Разделение кода и данных» и «выражение поведения программы как данных».

В вашем случае вы на самом деле беспокоитесь о втором и смешиваете первое в него. Когда вы выражаете поведение программы как данные, это облегчает расширение. В вашем примере с vowels = "aeiou"добавлением новой гласной так же просто, как и добавлением символа. Если у вас есть эти данные извне, вы можете изменить это поведение без перекомпиляции программы.

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

Euphoric
источник
2
Естественно, список гласных изменится.
Чао
13
@cHao Как только i18n вступает, это так .
Восстановить Монику
2
i18n может сломать вам голову - посмотрите некоторые извращенные примеры на Java в javaspecialists.eu/archive/Issue209.html
Рори Хантер,
2
@Angew: Как только i18n входит, ты все равно облажался . Вам нужен код для этого; Наивное решение не в состоянии обработать каждый случай, даже на английском языке. (Забудьте на ïсекунду; давайте поговорим о yи w!) Перемещение списка в базу данных не исправит это и на самом деле вредно - это сложность, которая будет бесполезной, если она сделана неправильно, но вы не будете даже знаю, что "не так" , если вы не разрабатываете для i18n с нуля. В этот момент вы уже понимаете, что список гласных просто не будет сокращать его в любом случае.
Чао
1
@BenLee: Я бы не удивился, на самом деле. В настоящее время я работаю над изменением некоторого подобного кода, пока мы говорим Но аутсорсинг всего в базу данных - это гадание совсем другого рода. Если вы еще не знаете, нужно ли что-то модифицировать - и что еще более важно, если вы еще не знаете, как это нужно будет модифицировать - тогда, IMO, лучше подождать, пока вам понадобится такая гибкость, прежде чем добавлять это. ,
cHao
5

Например, если функция вашей программы заключается в подсчете гласных, что плохого в том, что в них есть гласные = "aeiou"?

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

Вы упоминаете vowels = "aeiou", что если я иногда хочу "y", я должен перестроить всю программу? Могу ли я легко обновить версии теперь, когда я изменил код? Если есть ошибка, я ее вызвал или программа не работает?

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

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

Некоторые считают это противоположным, то есть вы удаляете опухоль кода из ваших ценных данных, см. Цитату Торвальдса о хорошем программисте

FMJaguar
источник
4
Цитата Торвальдса относится к структурам данных, а не к данным.
user949300
ОП гласит: «Объектно-ориентированное программирование говорит:« мы хотим сколь угодно богатые структуры данных », и поэтому наделило структуры данных возможностями кода».
FMJaguar
1
Если вы внесете фундаментальное изменение в определение того, что такое гласная, вам потребуется перезапустить все автоматизированные тесты. Системы редко, если вообще имеют возможность перезапускать тесты, когда файл конфигурации изменяется в развернутой системе. Таким образом, такие определения должны быть встроены в систему; возможно, в виде двух жестко закодированных наборов с возможностью конфигурации между ними.
сору
+1 за цитату Торвальдса. Я согласен с этим мнением: на примере кукол, я думаю, проблема в том, что у кукол нет хорошей структуры данных, чтобы представлять информацию, которую люди хотят в нее поместить. Вместо того, чтобы исправлять структуры данных, разработчики марионеток утверждали, что проблема заключается в «данных в коде» (почему? Это вопрос!), И разработали hiera , который, по моему мнению , немного больше, чем перемещение проблемы куда-то еще, и, кроме того, делает ее невозможной связать поведение с данными.
Фил Фрост
2

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

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

Но некоторые аргументы в пользу я вижу:

  • Если у вас есть образ мышления базы данных, то размещение справочных данных в базе данных SQL позволяет вам присоединиться к ним для составления отчетов.
  • Если у вас есть утилита администратора или доступ к базе данных, вы можете настроить значения во время выполнения. (Хотя это может быть игра с огнем.)

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

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

обкрадывать
источник
3
Хороший комментарий о процедурах магазина, где редактирование XML - это нормально, но редактирование того же самого в коде - большая проблема.
user949300
работал в одном магазине, где все было в базе данных, что может быть, вплоть до экранных текстов. Помимо кода пользовательского интерфейса, единственное , что не в базе данных было расположение базы данных и учетные данные ...
jwenting
3
это всегда звучит глупо, пока однажды кто-то не спросит «можем ли мы перенастроить это для пользователя X, который требует этого», и тогда это не кажется таким уж глупым. Черт, клиенты :)
gbjbaanb
2
... и если этот день "никогда", то это глупо долго
Роб
2

Позвольте мне задать вам совершенно серьезный контр-вопрос: в чем, на ваш взгляд, разница между «данными» и «кодом»?

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

Тип данных зависит от приложения; коммерческая система выставления счетов может хранить информацию о клиентах и ​​заказах в базе данных SQL, а программа векторной графики может хранить геометрические данные и метаданные в двоичном файле. В обоих случаях и между ними существует четкое и неразрывное разделение кода и данных. Данные принадлежат пользователю , а не программисту, поэтому они никогда не могут быть жестко запрограммированы.

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

Даже это определение, которое значительно менее неоднозначно, чем просто слово «данные», имеет несколько проблем. Например, что, если значимые части программы написаны на разных языках? Я лично работал над несколькими проектами, в которых примерно 50% C # и 50% JavaScript. Является ли код JavaScript "данными"? Большинство людей сказали бы нет. Как насчет HTML, это «данные»? Большинство людей все равно сказали бы нет.

Как насчет CSS? Это данные или код? Если мы думаем о коде как о чем-то, что контролирует поведение программы, то CSS на самом деле не код, потому что он только (ну, в основном) влияет на внешний вид, а не на поведение. Но на самом деле это не данные; пользователь не владеет им, приложение даже не владеет им. Это эквивалент кода для дизайнера пользовательского интерфейса. Это code- как , но не совсем код.

Я мог бы назвать CSS своего рода конфигурацией, но более практичным определением является то, что это просто код на предметно-ориентированном языке . Это то, что часто представляют ваши XML, YAML и другие «отформатированные файлы». И причина, по которой мы используем предметно-ориентированный язык, заключается в том, что, вообще говоря, он одновременно более лаконичен и более выразителен в своей конкретной области, чем кодирование той же информации на языке программирования общего назначения, таком как C или C # или Java.

Вы узнаете следующий формат?

{
    name: 'Jane Doe',
    age: 27,
    interests: ['cats', 'shoes']
}

Я уверен, что большинство людей делают; это JSON . И вот что интересного в JSON: в JavaScript это явно код, а на любом другом языке - четко отформатированные данные. Почти каждый основной язык программирования имеет по крайней мере одну библиотеку для "анализа" JSON.

Если мы используем тот же самый синтаксис внутри функции в файле JavaScript, он не может быть ничем иным, кроме кода. И все же, если мы возьмем этот JSON, поместим его в .jsonфайл и проанализируем в приложении Java, вдруг это «данные». Это действительно имеет смысл?

Я утверждаю, что «data-ness», «configuration-ness» или «code-ness» присуще тому , что описывается, а не тому, как оно описывается.

Если вашей программе нужен словарь из 1 миллиона слов, чтобы, скажем, генерировать случайную фразу-пароль, вы хотите закодировать ее следующим образом:

var words = new List<string>();
words.Add("aa");
words.Add("aah");
words.Add("ahhed");
// snip 172836 more lines
words.Add("zyzzyva");
words.Add("zyzzyvas");

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

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

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

Что я сказал младшим разработчикам, так это то, что они всегда должны выводить настройки, которые они ожидают изменить в каждой среде. Это включает в себя такие вещи, как строки подключения, имена пользователей, ключи API, пути к каталогам и так далее. Они могут быть одинаковыми на вашем устройстве разработки и на производстве, но, вероятно, нет, и системные администраторы решат, как они будут выглядеть в производстве, а не как разработчики. Таким образом, вам нужен способ применения одной группы настроек на некоторых машинах и других настроек на других машинах - например, внешних файлов конфигурации (или настроек в базе данных и т. Д.)

Но я подчеркиваю, что просто поместить некоторые «данные» в «файл» - это не то же самое, что перенести их в конфигурацию. Помещение словаря слов в текстовый файл не означает, что вы хотите, чтобы пользователи (или ИТ-специалисты) изменили его, это просто способ облегчить разработчикам понимание того, что происходит, и, при необходимости, сделать случайные изменения. Аналогичным образом, размещение той же информации в таблице базы данных не обязательно считается экстернализацией поведения, если таблица предназначена только для чтения и / или администраторы БД не должны с ней связываться. Конфигурация подразумевает, что данные являются изменяемыми, но в действительности это определяется процессом и обязанностями, а не выбором формата.

Итак, подведем итог:

  • «Код» не является жестко определенным термином. Если вы расширите свое определение, включив в него предметно-ориентированные языки и все остальное, что влияет на поведение, большая часть этого очевидного трения просто исчезнет, ​​и все это будет иметь смысл. Вы можете иметь не скомпилированный DSL-код в плоском файле.

  • «Данные» подразумевают информацию, которая принадлежит пользователю (-ам) или, по крайней мере, кому-либо, кроме разработчиков, и обычно недоступна во время разработки. Это не может быть жестко закодировано, даже если вы захотите это сделать. За возможным исключением самоизменяющегося кода , разделение между кодом и данными является вопросом определения, а не личных предпочтений.

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

  • Конфигурация представляет собой особый тип Soft-кодирование , что является необходимым , поскольку знания о том , что приложение может понадобиться для работы в различных средах. Развертывание отдельного файла конфигурации вместе с приложением является гораздо менее трудоемким (и гораздо менее опасным), чем развертывание другой версии кода в каждой среде. Таким образом, некоторые типы программного кодирования действительно полезны.

Aaronaught
источник
1

Я предлагаю прочитать эту классическую статью Орен Эйни (она же Ayende Rahien)

http://ayende.com/blog/3545/enabling-change-by-hard-coding-everything-the-smart-way

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

Таким образом, вы потенциально избегаете сложностей синтаксического анализа / интерпретации («но кто-то еще анализирует мой YAML / JSON» - отображение проанализированного текста в конкретные вызовы API может быть формой интерпретации) и избегаете сложности другого шага между «данными». и его использование.

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

orip
источник
1

Хорошо, давайте предположим, что вы хотите написать какую-нибудь программу на С ++ для вашего досуга. Вы точно знаете, что он должен делать, и что он никогда не должен будет делать. Теперь возьмите любую книгу на тему «Современный дизайн программного обеспечения». Вот правило игры: для каждого класса в вашем проекте и для каждого, даже такого крошечного случая, вы должны реализовать каждый причудливый шаблон, описанный в этой книге, чтобы сделать ваш код «чистым дизайном». Ну, «инъекции зависимости» будет достаточно для многих людей, я думаю. (Это с ++, а не java!) Программированию учат все более и более теоретически. Недостаточно, чтобы вы выполнили работу, вы должны написать код, который можно обслуживать, дурак доказать ... все хорошо и правильно. Проблема начинается, когда чел. Перестаньте думать о фактической причине, шаблоны проектирования были изобретены и стали догматичными.

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

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

Введите демона, владеющего догмой «обобщение и повторное использование»: - Почему бы не подсчитать какой-либо символ любого класса во входном потоке этого класса? (абстрагироваться от букв до битовых последовательностей произвольной, но конечной длины, поскольку это самое общее, что вы можете получить с помощью компьютера ...) - Подождите, даже тогда мы все еще будем считать в натуральных числах. Однако подсчет может быть обобщен как отображение из счетного множества на себя, выполняющего аксиомы ... [вы поняли идею]

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

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

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

К вашей конкретной проблеме: Если бы вы могли 1.) написать программу с максимальным количеством жесткого кодирования для вашего конкретного случая и затем 2.) обобщить из этого кода прямым способом, например. вводя больше аргументов функций и используя другие «тривиальные шаблоны», вы можете быть уверены, что разделяете код и данные, очевидным способом, как это было сделано с момента изобретения функционального программирования. (ofc вы пропускаете 1. и делаете 2. мгновенно ...)

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

Будем только надеяться, что xml-парсер, который вам тогда нужен, не нуждается в xml-config для работы ...

бхак
источник