Як поділ коду та даних стало практикою?


29

Будь ласка, уважно прочитайте питання: воно запитує як , а не чому .

Нещодавно я натрапив на цю відповідь , яка пропонує використовувати базу даних для зберігання незмінних даних:

Це звучить як багато магічних чисел, які ви описуєте - особливо якщо вони залежать від частини - це насправді дані, а не код. [...] Це може означати базу даних типу SQL, або може просто означати текстовий файл у форматі.

Мені здається, що якщо у вас є дані, які є частиною того, що робить ваша програма, то це потрібно зробити - це помістити їх у програму . Наприклад, якщо функцією вашої програми є підрахунок голосних, то що поганого в наявності vowels = "aeiou"в ній? Зрештою, більшість мов мають структури даних, розроблені саме для цього використання. Чому б вам не доводилося відокремлювати дані , розміщуючи їх у "форматованому текстовому файлі", як було запропоновано вище? Чому б просто не зробити цей текстовий файл відформатованим на вашій мові програмування? Тепер це база даних? Або це код?

Я впевнений, що деякі вважають це дурним питанням, але я задаю це з усією серйозністю. Я відчуваю, що "окремий код і дані" культурологічно стають як якась самоочевидна істина, поряд з іншими очевидними речами, такими як "не дайте своїм змінним вводити в оману імена" та "не уникайте використання пробілів просто тому, що ваша мова вважає це незначне ".

Візьмемо для прикладу цю статтю: Проблема з відокремленням даних від лялькового коду . Проблема ? Яка проблема? Якщо Лялька є мовою для опису моєї інфраструктури, чому вона не може також описати, що сервером імен є 8.8.8.8? Мені здається , що проблема полягає не в тому , що код і дані змішалися, 1 але Ляльковий не вистачає досить багаті структури даних і способи інтерфейсу до інших речей.

Я вважаю цю зміну тривожною. Об'єктно-орієнтоване програмування сказало, що "ми хочемо довільно багатих структур даних", і тому наділило структури даних повноваженнями коду. У результаті ви отримуєте інкапсуляцію та абстракцію. Навіть бази даних SQL мають збережені процедури. Коли ви секвеструєте дані в YAML або текстові файли або німі бази даних, ніби ви видаляєте пухлину з коду, ви втрачаєте все це.

Чи може хто-небудь пояснити, як з'явилася така практика відокремлення даних від коду і куди це відбувається? Чи може хтось цитувати публікації просвітників чи надати відповідні дані, які демонструють "окремий код від даних" як заповідь, що виникає, та ілюструє його походження?

1: якщо навіть можна зробити такі розрізнення. Я дивлюся на вас, програмісти Lisp.


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+ років), але галузь все більше наповнюється молоддю, і багато речей, які я вважав відомими, і вирішили продовжувати кидати виклик і винаходити, іноді виходять з нових прозріння, але іноді із незнання.


2
Чи можете ви розширити історію та тенденцію цієї практики? Якби кожен міркував про це, я б не ставив цього питання. Передумова питання полягає в тому, що люди не ретельно розглядають, куди мають переходити їх дані (компільовані константи, зовнішні бази даних, YAML ...), а вони думають лише про "КОДУВАННЯ І ДАНІ МІКСІДОВАНОГО БАДА! ХАЛЬ СМАШ!" Чому або коли це стало річчю?
Філ Мороз

Це не є частиною мого досвіду, тому я не можу вам сказати. До своєї відповіді я додав пару пара.
david.pfx

Я думаю, що "приплив молодих людей" є вагомим поясненням, але я тримаюсь від прийняття, тому що я хотів би почути від когось із цих молодих людей, щоб побачити, звідки у них ідея. Очевидно, що вони отримали частину "окремого коду та даних", але я не думаю, що вони отримали решту. Чи читали вони це в дописі в блозі? Книга? Де і коли?
Філ Мороз

Ви завжди отримаєте "_____ BAD! HULK SMASH!" - це не означає, що це правда. Часто подібні речі (наприклад, "" GOTO "BAD! HULK SMASH!") Навчають початківцям, не навчаючи їх чому, або які винятки.
AMADANON Inc.

Localityтакож працює в зворотному напрямку: ми закінчилися системою типу плагінів через користувацькі вимоги до різних клієнтів, і через кілька років проб і помилок навчилися зберігати їх константи (навіть таблиці, за допомогою списків диктів) бази даних та в коді. І тому, що використовувати його в будь-якому місці, окрім цього «плагіна», є неправильним, а також тому, що зміни відбуваються автоматично, коли зміни відбуваються.
Ізката

8

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

дозволи

Якщо дані жорстко закодовані, вам потрібно буде відредагувати вихідний файл, щоб відредагувати ці дані. Це означає, що або:

  • Лише розробники можуть редагувати дані. Це погано - введення даних - це не те, що вимагає навичок та знань розробника.

  • Не розробники можуть редагувати вихідний файл. Це погано - вони можуть викрутити вихідний файл, навіть не підозрюючи про це!

  • Дані жорстко кодуються в окремі вихідні файли, і не розробники мають доступ лише до цих файлів. Але це насправді не рахується - тепер дані відокремлені від коду та зберігаються у власних файлах ...

редагування

Отже, щодо того, хто може редагувати дані, найкраще зберігати їх окремо. Як щодо того, як вони будуть редагувати дані? Якщо у вас багато даних, введення вручну є втомливим і помилковим. Мати для цього якийсь інтерфейс набагато краще! Навіть якщо вам все-таки доведеться все вводити, вам не доведеться вводити котлову форму формату, тому менше шансів ви зіпсувати формат і закрутити весь файл!

Якщо дані жорстко закодовані, створення цього інтерфейсу означатиме, що автоматичний інструмент буде редагувати написані вами вручну файли. Нехай це зануриться - автоматичний інструмент відкриє ваші вихідні файли, спробує знайти, де мають бути дані, та змінить цей код. Бррр ... Microsoft представила часткові класи на C #, щоб уникнути цих речей ...

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

масштабування

Код і масштаб даних дуже різний. Коли ваш код зростає, ви хочете розділити його на більше класів і методів (або структур даних і функцій), але ваші дані - незалежно від того, скільки вони зростають - ви хочете зберегти в одному місці. Навіть якщо вам доведеться розділити їх на кілька файлів, ви хочете якось зв’язати ці файли разом, тож буде легше отримати доступ до цих даних з коду.

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

пошук

У вас є тонна даних - це природно, що вам захочеться пошукати їх.

  • Якщо ви зберігаєте його в базі даних - ви можете використовувати мову запитів до бази даних.

  • Якщо ви зберігаєте його у XML-файлі - ви можете використовувати XPath.

  • Якщо ви зберігаєте його в JSON / YAML - ви можете завантажити його у відповідь улюбленої мови сценаріїв і виконати пошук.

  • Навіть якщо ви зберігаєте його у звичайному старому текстовому файлі, оскільки він має структуру, яку ваша програма може розпізнати, ви можете використовувати grep / sed / awk для його пошуку.

Хоча це правда, що ви також можете перекочувати / sed / awk за допомогою жорстко закодованих даних у вихідному файлі, він не працює так добре, оскільки ваш запит може збігатися з іншими, не пов’язаними між собою рядками, або пропускати рядки, записані інакше, оскільки синтаксис подання даних мови програмування дозволяє це.

Існують інструменти пошуку за кодом, але вони хороші для пошуку декларацій, а не жорстких кодованих даних.

Це сумно...

Дуже важливо розрізняти дані та код. Просто те, що щось написано як код, не означає, що це не може бути даними. І те, що щось написано з поданням даних, не означає, що це насправді не код.

У мене був клас, коли у нас були дуже суворі правила щодо "магічних чисел" - ми не могли мати жодного числа в нашому коді. Це означає, що нам довелося робити такі речі:

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

що відверто смішно! Так, 0це технічно "дані", але це так само, як частина коду, як і решта forциклу! Тож навіть якщо ми можемо представити його як дані та відокремити його від коду, це не означає, що ми повинні . Не тому, що ми хочемо залишити дані всередині коду, а тому, що це насправді не дані - не більше ніж решта коду, який також компілюється в цілі та нулі ...


7

Я думаю, що відбувається деяка плутанина. Ви поєднуєте дві речі разом: "Розмежування коду та даних" та "вираження поведінки програми як даних".

У вашому випадку ви насправді переживаєте за друге і змішуєте перше в ньому. Якщо ви виражаєте поведінку програми як дані, це полегшує її розширення. У вашому прикладі з vowels = "aeiou", додавання нового голосного так само просто, як і додавання символу. Якщо у вас є ці дані зовні, ви можете змінити цю поведінку без необхідності перекомпілювати програму.

І коли ви думаєте про це, OOP є продовженням цього мислення. Об’єднання даних та поведінки разом дозволять змінити поведінку програми на основі даних програми.


2
Тому що, природно, список голосних буде змінено.
cHao

13
@cHao Як тільки i18n вступає, це так .
Відновіть Моніку

2
i18n може зламати голову - дивіться кілька збочених прикладів на Java у javaspecialists.eu/archive/Issue209.html
Rory Hunter

2
@Angew: Як тільки i18n вступає, все-таки ти все одно накрутився . Для цього вам потрібен код; наївне рішення не в змозі впоратися з усіма випадками навіть англійською мовою. (Забудьте на ïсекунду; поговоримо про yта w!) Переміщення списку в базу даних це не виправить, і насправді шкідливо - це складність, яка буде марною, якщо зробити неправильно, але ви не будете навіть знайте, що "не так" , якщо ви не розробляєте i18n з нуля. У цей момент ви вже усвідомлюєте, що список голосних голосів просто не збирається розрізати.
cHao

1
@BenLee: Насправді, я не був би трохи здивований. Зараз я працюю над зміною такого коду, як ми говоримо. Але аутсорсинг всього на базу даних - це ворожість зовсім іншого типу. Якщо ви вже не знаєте, чи потрібно щось модифікувати - і що ще важливіше, якщо ви ще не знаєте, як це потрібно буде модифікувати - тоді ІМО краще почекати, поки вам не потрібна ця гнучкість, перш ніж додавати це .
cHao

5

Наприклад, якщо функцією вашої програми є підрахунок голосних звуків, то що поганого в тому, щоб у ній були голосні = "aeiou"?

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

Ви згадуєте голосні = "aeiou", що, якщо я іноді хочу "у", я повинен перебудувати всю програму? Чи можу я легко оновити версії тепер, коли я змінив код? Якщо є помилка, я її спричинив, або програма зламана?

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

Коли ви секвеструєте дані в YAML або текстові файли або німі бази даних, ніби ви видаляєте пухлину з коду

Деякі вважають це навпаки, тобто ви видаляєте пухлину коду зі своїх дорогоцінних даних, див .: Цитата Торвальда про хорошого програміста


4
Цитата Торвальда стосується структури даних, а не даних.
user949300

ОП зазначає: "Об'єктно-орієнтоване програмування сказало, що" ми хочемо довільно багатих структур даних ", і тому наділило структури даних повноваженнями коду".
FMJaguar

1
Якщо ви внесете принципові зміни у визначення того, що таке голосна, вам потрібно буде повторно застосувати всі автоматизовані тести. Системи рідко, якщо коли-небудь мають можливість повторно проводити тести, коли змінюється файл конфігурації у розгорнутій системі. Тому такі визначення потрібно вбудовувати в систему; можливо, як два жорстко закодованих набори з можливістю налаштування для вибору між ними.
сор

+1 за цитатою Торвальда. Я погоджуюся з цим почуттям: на прикладі маріонетки я думаю, що проблема полягає в тому, що маріонетка не має гарної структури даних, яка б представляла інформацію, яку люди хочуть внести в неї. Замість того, щоб виправити структури даних, розробники ляльок стверджували, що "дані в коді" є проблемою (чому? Це питання!) Та розробили ієру , яку я бачу як дещо більше, ніж переміщення проблеми кудись інше, і додатково унеможливлюючи її пов'язувати поведінку з даними.
Філ Мороз

2

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

Зараз я все ще думаю, що це було дурним рішенням, і якби у нас не була інфраструктура, я просто не зробив би цього.

Але я бачу деякі аргументи на користь:

  • Якщо у вас є умонастрій бази даних, то введення довідкових даних у базу даних SQL дозволяє приєднатись до неї для звітування.
  • Якщо у вас є утиліта адміністратора або доступ до бази даних, ви можете налаштувати значення під час виконання. (Хоча це може грати з вогнем.)

Крім того, іноді політика перешкоджає практиці кодування. Наприклад, я працював у декількох магазинах, де для натискання .xml-файла A-OK, а торкання рядка в коді вимагає повного циклу регресії та, можливо, тесту навантаження. Отож, у мене була одна команда, де мої файли .xml для проекту були надзвичайно багаті (і, можливо, -heh-, можливо, містили якийсь код).

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


3
Хороший коментар щодо торгових процедур, де редагування XML - це "нормально", але редагування того ж самого коду - це великі клопоти.
user949300

працював в одному магазині, де все було в базі даних, що могло бути, аж до екранів текстів. Крім коду користувальницького інтерфейсу, єдине, що не було в базі даних, було розташування бази даних та облікові дані ...
jwenting

3
це завжди звучить нерозумно, поки одного разу хтось не запитає: "чи можемо ми перенастроїти це для користувача X, який вимагає цього", і тоді це не здасться таким нерозумним. Прокляті клієнти :)
gbjbaanb

2
... і якщо цей день "ніколи", то це довго відчувати себе дурним
Роб

2

Дозвольте поставити вам цілком серйозне зустрічне запитання: чим, на ваш погляд, різниця між "даними" та "кодом"?

Коли я чую слово "дані", я думаю "стан". Дані, за визначенням, це те, що сама програма призначена для управління, а тому сама річ, про яку програма ніколи не може знати про час компіляції. Неможливо ввімкнути дані жорсткого коду, тому що як тільки ви його жорстко кодуєте, це стає поведінкою, а не даними.

Тип даних змінюється залежно від програми; комерційна система виставлення рахунків може зберігати інформацію про клієнтів і замовляти в базі даних SQL, а векторно-графічна програма може зберігати дані геометрії та метадані у двійковому файлі. І в обох цих випадках, і в усьому між ними існує чітке і нерозривне розділення коду та даних. Дані належать користувачеві , а не програмісту, тому вони ніколи не можуть бути жорстко кодованими.

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

Навіть це визначення, яке є значно менш неоднозначним, ніж просто слово "дані", має кілька проблем. Наприклад, що робити, якщо значні частини програми написані різними мовами? Я особисто працював над декількома проектами, які складають близько 50% C # і 50% JavaScript. Чи код JavaScript "дані"? Більшість людей скажуть "ні". Що з HTML, це "дані"? Більшість людей все одно скажуть ні.

Що з CSS? Це дані чи код? Якщо ми вважаємо код тим, що контролює поведінку програми, то CSS насправді не є кодом, оскільки він впливає лише на зовнішній вигляд, а не на поведінку. Але це насправді не дані; користувач не володіє ним, додаток навіть не є ним. Це еквівалент коду для дизайнера інтерфейсу. Це схоже на код, але не зовсім код.

Я можу назвати CSS своєрідною конфігурацією, але більш практичним визначенням є те, що це просто код на доменній мові . Ось що часто представляють ваші XML, YAML та інші "відформатовані файли". І тому, що ми використовуємо мову, що залежить від домену, є те, що, як правило, він є одночасно більш стислим і виразним у своєму конкретному домені, ніж кодування тієї самої інформації на загальноприйнятій мові програмування, як C або C # або Java.

Ви впізнаєте наступний формат?

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

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

Якщо ми використовуємо такий самий синтаксис всередині функції у файлі JavaScript, він не може бути іншим, крім коду. І все ж, якщо ми візьмемо той JSON, засуньте його у .jsonфайл та розберемо у додатку Java, раптом це "дані". Це справді має сенс?

Я стверджую, що "дані-ніс" або "конфігурація-ніс" або "кодо-ніс" притаманні тому , що описується, а не тому, як це описується.

Якщо вашій програмі потрібен словник в 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, шляхи до каталогу тощо. Вони можуть бути однаковими на вашому коробці розробників і на виробництві, але, мабуть, ні, і сисадміни вирішать, як вони хочуть, щоб це виглядало у виробництві, а не в чортах. Отже, вам потрібен спосіб застосування однієї групи налаштувань, застосованих на деяких машинах, а інших налаштувань, застосованих на інших машинах - ерго, зовнішні файли конфігурації (або налаштування в базі даних тощо).

Але підкреслюю, що просто вводити якісь "дані" у "файл" - це не те саме, що ексстерналізувати їх як конфігурацію. Введення словника слів у текстовий файл не означає, що ви хочете, щоб користувачі (або ІТ) його міняли, це лише спосіб полегшити розробникам зрозуміти, що, до біса, і, якщо потрібно, зробити епізодичні зміни. Аналогічно, введення тієї самої інформації в таблицю бази даних не обов'язково вважається екстерналізацією поведінки, якщо таблиця є лише для читання і / або DBA доручається ніколи не накручувати її. Конфігурація означає, що дані є змінними, але насправді це визначається процесом та обов'язками, а не вибором формату.

Отже, підсумовуючи:

  • "Код" не є жорстко визначеним терміном. Якщо ви розширите своє визначення, щоб включити доменні мови та все інше, що впливає на поведінку, багато цього очевидного тертя просто зникне, і це матиме сенс. Ви можете мати некомпільований DSL "код" у плоскому файлі.

  • "Дані" мають на увазі інформацію, що належить користувачеві або користувачам або принаймні комусь, крім розробників, і, як правило, не доступна під час проектування. Це не може бути жорстко закодовано, навіть якщо ви цього хотіли. За можливим винятком коду , що самозмінюється , розділення між кодом та даними є питанням визначення, а не особистих переваг.

  • "М'яке кодування" може бути жахливою практикою при надмірному застосуванні, але не кожен екземпляр екстерналізації обов'язково становить програмне кодування, і багато випадків зберігання інформації у "плоских файлах" не обов'язково є добросовісною спробою екстерналізації.

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


1

Я пропоную прочитати цю класичну статтю Орена Ейні (він же Айенде Рахієн)

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

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

Таким чином, ви потенційно уникнете складності розбору / інтерпретації ("але хтось інший розбирає мій YAML / JSON" - зіставлення розбору тексту в конкретні виклики API може бути формою інтерпретації), і уникаєте складності іншого кроку між "даними" "та його використання.

Деякі випадки піддаються вираженню даних навіть у такому сценарії: наприклад, вказівка ​​тисяч точок у тривимірному просторі може бути краще підходить для текстового файлу, ніж код, хоча в деяких мовах, включаючи C, використовуючи ініціалізатори структури, код може бути доречним навіть для цього.


1

Гаразд, припустимо, ви хочете написати якусь програму c ++ для свого дозвілля. Ви точно знаєте, що вона має робити і що ніколи не потрібно буде робити. Тепер візьміть будь-яку книгу на тему "сучасний дизайн програмного забезпечення". Ось правило гри: Для кожного класу у вашому проекті та кожного навіть такого крихітного випадку вам потрібно реалізувати кожен вишуканий зразок, який ви знайдете, описаний у цій книзі, щоб зробити ваш код «чистим дизайном». Що ж, "введення залежності" буде достатньо для багатьох ppl, я думаю. (Це c ++, а не java!) Програмування викладається з більш теоретичної точки зору. Недостатньо, щоб ви виконали роботу, ви повинні написати код, який можна підтримувати, дурень доводить ... все добре і правильно. Проблема починається, коли ppl. перестаньте думати про фактичну причину, дизайнерські зразки були винайдені і стали догматичними.

Дозвольте мені зупинити вас на написанні інструменту підрахунку листів (над), використовуючи єдиний простий принцип designe: Коли ви пишете код, який виконує певну роботу на вхідних даних певного типу, переконайтеся, що він здатний виконати це завдання для будь-якого даного вводу дані цього типу. - Коли ви хочете написати інструмент літер-лічильник, явно має сенс записати його таким чином, щоб він міг не тільки рахувати голосні, але і "будь-яку букву". - Оскільки ви, можливо, не знаєте, що насправді розбирає корпус, який ви розбираєте, ви можете також вибрати дуже загальне кодування (UTF-16) і охопити більшість (усіх?) Письмових мов та їх символів.

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

Введіть демон, що володіє догмою "узагальнення та повторного використання": - Чому б не порахувати жоден символ будь-якого класу у вхідному потоці цього класу? (реферат від букв до бітових послідовностей довільної, але кінцевої довжини, оскільки це найзагальніше, що можна отримати за допомогою комп'ютера ...) - Зачекайте, навіть тоді ми все ще підраховуємо в натуральних числах. Однак підрахунок може бути узагальнений як зіставлення з обчислювальної множини до себе, що виконує аксіоми ... [ви отримуєте ідею]

Тепер цей приклад може бути нерозумним, але якщо ви розглядаєте більш складні завдання дизайну, ніж інструмент для підрахунку, ви можете знайти всі можливості ввести додаткову абстракцію, необхідну відповідно до певного шаблону дизайну, який ви знайшли у своїй книзі.

Відокремлення "даних" та "коду", ймовірно, буде або тривіальним (аргументи функції), або ви опинитесь до інваріантів як до змінних ("дані").

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

До вашої конкретної проблеми: Якщо ви могли б 1.) написати програму з максимумом жорсткого кодування для вашого конкретного випадку, а потім 2.) узагальнити цей код прямо прямим шляхом, наприклад. вводячи більше аргументів функції та використовуючи інші "тривіальні шаблони", ви можете бути впевнені, що ви розділяєте код і дані, очевидним способом, як це було зроблено з часу винайдення функціонального програмування. (ofc ви пропускаєте 1. і робите 2. моментально ...)

Що-небудь не очевидне тут, швидше за все, є випадком "теорії-тупикової ситуації": як написання інтерфейсу, що переглядає інтерфейс та ще один інтерф ... і в кінці у вас є акуратний маленький xml-файл для налаштування всіх цих інтерфейсів. і залежності, які потрібно вводити у ваш клас-інтерфейс.

Будемо просто сподіватися, що xml-аналізатор, який ви тоді потребуєте, не потребує xml-конфігурації для роботи ...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.