В чем разница между данными и кодом? - PullRequest
14 голосов
/ 13 марта 2009

В качестве примера рассмотрим набор скидок, доступных покупателю супермаркета.

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

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

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

Или это точка объектно-ориентированного проектирования, чтобы мы не беспокоились о границе между данными и кодом?

Чтобы уточнить, основной вопрос заключается в следующем: как бы вы кодировали приведенный выше пример? Есть ли эмпирическое правило, которое заставило вас решить, что такое данные и что такое код?

(Примечание: я знаю, код может быть скомпилирован, но в мире динамических языков и JIT-компиляции, даже это размытое понятие.)

Ответы [ 13 ]

8 голосов
/ 13 марта 2009

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

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

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

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

5 голосов
/ 13 марта 2009

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

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

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

Для компилятора (или виртуальной машины) код - это фактически данные, над которыми он выполняет свои операции. Однако код для компиляции не определяет поведение для компилятора, это делает собственный код компилятора.

2 голосов
/ 13 марта 2009

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

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

2 голосов
/ 13 марта 2009

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

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

1 голос
/ 23 мая 2019

Огромная разница. Данные передаются системе, а код является частью системы.

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

Например, давайте рассмотрим некоторые JSON, некоторые плохие коды parser.js мной и скажем, хороший V8. Для моей системы плохой parser.js - это код, и моя система работает неправильно. Но для системы Google мой плохой парсер - это данные, которые ни о чем не говорят о качестве V8.

Вопрос очень практичный, не сложный. https://en.wikipedia.org/wiki/Systems_engineering пытается сделать хороший ответ и деньги.

1 голос
/ 13 марта 2009

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

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

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

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

1 голос
/ 13 марта 2009

В Лиспе ваш код - это данные, а ваш данные код

В прологе есть термины и термины являются пунктами.

0 голосов
/ 10 октября 2014

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

0 голосов
/ 13 марта 2009

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

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

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

Также Программа может извлекать код, преобразовывать код, загружать код, генерировать код tooooooo ...

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

Например, *

Sourcecontrolsystem process Исходные коды

здесь сам исходный код является кодом

Файлы процесса резервного копирования

здесь файлы - это данные и так далее ...

0 голосов
/ 13 марта 2009

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

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

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

Это очень мощный способ проектирования.

Применив это к основному вопросу («Как бы вы закодировали приведенный выше пример?»), Можно было бы выбрать или разработать высокоуровневый предметно-ориентированный язык (DSL) для определения правил. При запуске или при первой необходимости сервер считывает правило и выполняет его.

Предоставляет интерфейс администратора, позволяющий администратору

  • протестировать новый файл правил
  • заменить текущую конфигурацию конфигурацией из нового файла правил

... все это произойдет во время выполнения.

DSL может быть чем-то таким же простым, как анализатор таблиц или синтаксический анализатор XML, или может быть чем-то более сложным, чем язык сценариев. Из C легко встроить Python или Lua. Из Java легко встроить Groovy или Clojure.

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

...