Що таке "м'яке кодування" насправді?


87

У цій статті Олексія Пападімуліса ви можете побачити цей фрагмент:

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {

    //SR008-04X/I are always required in these states
    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
    attachDocument("AUTHCNS-1A");
  }
}

Я справді не розумію цю статтю.

Цитую:

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

Це аргумент проти того, щоб постійне ціле число "500000" було у файлі конфігурації або "AUTHCNS-1A" та інші рядкові константи.

Як це може бути поганою практикою?

У цьому фрагменті "500000" - це не число. Наприклад, це не те саме, що:

int doubleMe(int a) { return a * 2;}

де 2 - число, яке не потрібно абстрагувати. Його використання очевидно, і воно не являє собою те, що згодом може бути повторно використане.

Навпаки, "500000" - це не просто число. Це значна цінність, яка представляє ідею точки перелому у функціональності. Цей номер можна використовувати в більш ніж одному місці, але це не число, яке ви використовуєте; це ідея межі / межі, нижче якої застосовується одне правило, а над яким інше.

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

Крім того, якщо завтра уряд вимагає "З 5/3/2050, вам потрібно додати AUTHLDG-122B замість AUTHLDG-1A", ця строкова константа не є простою постійною константою. Це те, що представляє ідею; це лише поточне значення цієї ідеї (це "те, що ви додаєте, якщо головна книга вище 500 к").

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

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


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

2
Конфігурація має бути зарезервована для речей, які потрібно налаштувати. Якщо бізнес-правила взагалі не налаштовані, то введення бітів у конфігурацію все одно не купує нічого.
biziclop

Для належно розширених мов конфігурація має форму фактичних підпрограм, а не рядків.
Thorbjørn Ravn Andersen

Відповіді:


100

Автор застерігає від передчасної абстракції.

Ця лінія if (ledgerAmt > 500000)виглядає як правило, яке ви б очікували побачити для великих складних бізнес-систем, вимоги яких неймовірно складні, але точні та добре зафіксовані.

Зазвичай такі вимоги є винятковими / кращими випадками, а не корисною логікою багаторазового використання. Ці вимоги зазвичай належать та підтримуються бізнес-аналітиками та експертами з питань тематики, а не інженерами

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

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

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

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

Розглянемо інший (не менш вірогідний) сценарій, коли він 500000відображається в декількох місцях у документі з вимогами, але експерти з питань предмета вирішують змінити лише один із них; там у вас є ще гірший ризик того, що хтось змінить constзначення, можливо, не зрозуміє, що 500000використовується, щоб означати різні речі - тому розробник змінює його на єдине і єдине місце, де він / вона знаходить це в коді, і в кінцевому підсумку порушує щось, що вони не розуміли, що вони змінилися.

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

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

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


28
Мова, визначений для домену (DSL), може бути хорошим способом зробити код читати більше як документ вимоги.
Ян

13
Ще однією перевагою DSL є те, що також ускладнює випадкове поєднання логіки програми, презентації чи стійкості з правилами бізнесу.
Ерік Ейдт

16
Думаючи, що ваша заява є достатньо спеціальною, щоб гарантувати власну DSL, це, як правило, обман.
brian_o

8
Those requirements are typically owned and maintained by business analysts and subject matter experts, rather than by engineersщо не завжди є хорошою ідеєю. Іноді акт перетворення цих вимог у код виявить кутові випадки, коли вимоги або недостатньо чітко визначені, або визначені таким чином, що це суперечить інтересам бізнесу. Якщо бізнес-аналітики та розробники можуть співпрацювати над досягненням спільної мети, то можна уникнути багатьох проблем.
kasperd

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

44

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

Крім того, завтра уряд іде "З 5/3/2050, вам потрібно додати AUTHLDG-122B замість AUTHLDG-1A".

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

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

Звідки ви знаєте, що згодом вам це не знадобиться? Або хтось інший з цього питання?

У цьому полягає принцип принципу YAGNI. Не розробляйте для невідомого майбутнього, яке може виявитися зовсім іншим, дизайн для сьогодення. Ви вірні, що якщо значення 500000 використовується декількома місцями в програмі, його, звичайно, слід витягувати до постійної величини. Але це не так у коді, про який йдеться.

Програмне кодування - це справді питання роз'єднання проблем . Інформація про програмний код, яку ви знаєте, може змінюватися незалежно від основної логіки програми. Ви ніколи не будете жорстко кодувати рядок підключення до бази даних, оскільки знаєте, що вона може змінюватися незалежно від логіки програми, і вам потрібно буде диференціювати її для різних середовищ. У веб-додатку ми любимо відокремлювати бізнес-логіку від HTML-шаблонів та таблиць стилів, оскільки вони можуть змінюватися незалежно і навіть змінюватися різними людьми.

Але у випадку з зразком коду рядки та цифри з твердим кодом є невід’ємною частиною логіки програми. Можливо, що один файл може змінити своє ім'я через певну зміну політики, яка не є вашим контролем, але це так само мислимо, що нам потрібно додати нову перевірку, якщо філія для іншого стану. Витяг імен та чисел файлів фактично порушує згуртованість у цьому випадку.


4
Часто змінювати код набагато складніше, ніж файл конфігурації. Можливо, вам знадобляться розробник та система збирання / цикл випуску для першого, тоді як для останнього потрібно лише змінити номер у полі в дружньому інтерфейсі конфігурації.
OrangeDog

6
@OrangeDog Так, це спочатку виглядає. Але якщо ви робите подібні речі, інтерфейс конфігурації стане будь-яким, крім дружнього, із сотнями абсолютно безглуздих текстових полів, які запитують вас, хто що знає. А тепер вам потрібно побудувати інтерфейс користувача і документувати його. Зауважте, це не означає, що конфігурація ніколи не є хорошим шляхом - є випадки, коли це абсолютно правильний вибір. Але не в жодному із прикладів статті. А коли востаннє законодавство змінило саме кількість? Востаннє тут змінювались правила ПДВ, нам довелося все-таки переробити всі розрахунки.
Луань

2
@OrangeDog: Тут ви припускаєте, що конфігурація програмного забезпечення забезпечує вам необхідні гачки для перевірки, яку вам потрібно зробити. Зверніть увагу, як в ОП кожен ifбазується на різній змінній! Якщо потрібна змінна недоступна з конфігурації, вам все одно потрібно змінити програмне забезпечення.
Матьє М.

2
@OrangeDog, тому ви припускаєте, що слід змінити логіку програмного додатку без циклу dev / qa / реліз та відповідного тестування?
NPSF3000

3
@OrangeDog: Гаразд, ви використовуєте YAML для налаштування логіки в прикладі. Оскільки логіка включає умовні правила, ви знайдете спосіб представити ці умовні умови в YAML. Вітаємо, ви переробили Python. Чому б тоді не написати цілу програму в Python?
ЖакБ

26

У статті йдеться про «Enterprise Rule Engine», який, мабуть, є кращим прикладом того, про що він сперечається.

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

Наприклад, код стану для відображення документа в прикладі можна перемістити у файл конфігурації. Але тоді вам потрібно було б висловити складні стосунки.

<statecode id="AZ">
    <document id="SR008-04X"/>
    <document id="SR008-04XI"/>
</statecode>

Можливо, ви також поклали б у величину книги?

<statecode id="ALL">
    <document id="AUTHLDG-1A" rule="ledgerAmt >= 50000"/>
</statecode>

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

Слід зазначити, що ця стаття є з 2007 року, коли подібні речі були загальним підходом.

Сьогодні ми, мабуть, вирішимо проблему із введенням залежності (DI). Тобто, у вас було б "жорстке кодування"

InvoiceRules_America2007 : InvoiceRules

які ви замінили б на жорсткому коду або більше налаштовували

InvoiceRules_America2008 : InvoiceRules

коли змінилися законодавчі чи ділові вимоги.


4
Можливо, вам слід визначити "DI". І, можливо, поясніть трохи більше.
Василь Бурк

9
Чому цього файлу не було в системі управління джерелом?
JDługosz

2
Якщо це специфічно для клієнта, чи має кодована версія величезну безладність ifтверджень, щоб дати різні значення для кожного клієнта? Це звучить як щось, що має бути у файлі конфігурації. Перебуваючи в тому чи іншому файлі чи іншому, при рівності інших, це не привід не контролювати / відслідковувати / створювати резервну копію файлу. @ewan, здається, говорить, що файл DSL чомусь не може бути збережений як частина проекту, коли, безумовно, є навіть нематеріальні активи, такі як зображення та звукові файли та документація .
JDługosz

2
Ви дійсно повинні переробити значення "50000" зі свого XML і помістити його в окремий файл конфігурації, ви не думаєте? ... а це, до речі, має бути 500000.
Уайлдкард

1
@jdlugosz концепція ERE полягає в тому, що ви купуєте систему, а потім налаштовуєте її для своїх потреб. можливо тому, що внутрішні розробники конкурували з цими "гнучкими" системами, вони намагалися би імітувати їх. Зміна контролю над конфігурацією, навіть у таких системах великих компаній, як IBM, часто була думкою. Місце продажу було швидкою зміною
Еван

17

Навпаки, "500000" - це не просто число. Це значна цінність, яка представляє ідею точки перелому у функціональності. Це число можна використовувати в декількох місцях, але це не число, яке ви використовуєте, це ідея межі / межі, нижче якої застосовується одне правило, а над якою інша.

І це виражається тим, що (і я можу стверджувати, що навіть коментар є зайвим):

 if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

Це просто повторення того, що робить код:

LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000
if (ledgerAmnt >= LEDGER_AMOUNT_REQUIRING_AUTHLDG1A) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
}

Зауважте, автор припускає, що значення 500000 пов'язане з цим правилом; це не значення, яке може бути використане або, можливо, повторно використане в іншому місці:

Єдине зміна бізнес-правил, яке могло б коли-небудь спричинити це попереднє програмне кодування, - це зміна суми книги, яка вимагала форми AUTHLDG-1A. Будь-яка інша зміна правил бізнесу вимагає ще більшої роботи - конфігурація, документація, код тощо

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


2
Якщо ви ввели константу LEDGER_AMOUNT_REQUIRING_AUTHLDG1A, ви більше не впишете коментар у код. Коментарі програмісти не підтримуються добре. Якщо сума коли-небудь змінилася, ifумова та коментар вийдуть із синхронізації. Навпаки, константа LEDGER_AMOUNT_REQUIRING_AUTHLDG1Aніколи не виходить із синхронізації із самим собою, і це пояснює її призначення без зайвих коментарів.
ZeroOne

2
@ZeroOne: За винятком випадків, якщо правило бізнесу зміниться на "Книга 500 Кб або більше вимагає AUTHLDG-1A та AUTHLDG-2B", велика ймовірність, що особа, яка додає attachDocument("AUTHLDG-2B");рядок, не зможе одночасно оновити ім'я постійного імені. У цьому випадку я думаю, що код є досить чітким, не має коментаря, ані змінної пояснювача. (Хоча це може мати сенс скласти конвенцію із зазначенням відповідного розділу документа про вимоги бізнесу через коментарі до коду. Відповідно до такої конвенції, коментар до коду, який робить це доречним тут.)
ruakh

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

1
@ZeroOne: Але для AUTHLDG-3C кількість головної книги насправді є максимальною . А для AUTHLDG-4D відповідна величина книги залежить від стану. (Чи зрозуміли ви ще? Для цього типу коду ви хочете, щоб ваш код відображав бізнес-правила, а не якусь спробу абстрагування бізнес-правил, тому що немає підстав очікувати еволюції бізнес-правил у відповідності з абстракції, які ти прийняв.)
ruakh

2
Особисто я не заперечую проти введення магічного числа в код, я заперечую проти структуризації коду, щоб він потребував цих коментарів. Якби це я, я зробив би кожен документ екземпляром enum зі своїм attachIfNecessary()методом і просто перекинувся на них.
Девід Молес

8

Інші відповіді правильні та продумані. Але ось моя коротка і мила відповідь.

  Rule/value          |      At Runtime, rule/value…
  appears in code:    |   …Is fixed          …Changes
----------------------|------------------------------------
                      |                 |
  Once                |   Hard-code     |   Externalize
                      |                 |   (soft-code)
                      |                 |
                      |------------------------------------
                      |                 |
  More than once      |   Soft-code     |   Externalize
                      |   (internal)    |   (soft-code)
                      |                 |
                      |------------------------------------

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

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

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


1
Мені подобається ваша відповідь, але я думаю, ви також повинні врахувати, чи зміниться вона при впровадженні. Це в основному актуально, якщо річ є продуктом, який буде використовуватися у багатьох організаціях, які, наприклад, можуть мати різні правила щодо того, чи потрібно керівнику затверджувати відшкодування через X тощо тощо
Bloke Down The Pub

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

7

Це пастка, в яку ми потрапляємо, коли ми використовуємо проблему з іграшками, а потім ставимо лише солом’яні рішення, коли ми намагаємось проілюструвати реальну проблему.

У наведеному прикладі не має різниці, чи вказані значення твердо кодуються як вбудовані значення чи визначаються як consts.

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

Дивіться, якщо є код, який його оточує, то погані речі явно трапляються.

Перша погана річ полягає в тому, що значення 50000 використовується десь іншим значенням, скажімо, величиною книги, над якою змінюється ставка податку в деяких штатах ... тоді, коли зміни відбуваються, обслуговуючий не може знати, коли він знаходить ці два екземпляри 50000 в коді, означають вони ті самі 50k або цілком не пов'язані 50ks. І чи слід також шукати 49999 та 50001, якщо хтось також використовував їх як константи? Це не заклик до розміщення цих змінних у конфігураційному файлі окремої служби: але жорстке кодування їх вбудовано, очевидно, також неправильно. Натомість вони повинні бути константами, визначеними та розміщеними в межах класу чи файлу, в якому вони використовуються. Якщо два екземпляри 50k використовують однакову константу, вони, ймовірно, представляють однакове законодавче обмеження; якщо ні, вони, ймовірно, ні; і в будь-якому випадку вони матимуть ім'я,

Імена файлів передаються функції - attachDocument () - яка приймає основні назви файлів як рядок, без шляху чи розширення. Файли файлів, по суті, є зовнішніми ключами до якоїсь файлової системи чи бази даних, або де б файл attachDocument () не отримував файли. Але рядки нічого не говорять про це - скільки файлів є? Які типи файлів вони є? Як ви знаєте, відкриваючи на новий ринок, чи потрібно оновлювати цю функцію? До яких видів речей їх можна прикріпити? Обслуговувач залишається повністю в темряві, і все, що він має, - це рядок, який може з'являтися в коді кілька разів і означати різні речі кожного разу, коли він з'являється. В одному місці "SR008-04X" - це чіт-код. В іншому - це команда замовити чотири ракетні ракети SR008. Ось це sa ім'я файлу? Чи пов'язані вони? Хтось просто змінив цю функцію, щоб згадати ще один файл, "КЛІЄНТ". Тоді вам, поганому обслуговуючому працівнику, сказали, що файл "КЛІЄНТ" потрібно перейменувати на "ЗАМОВНИК". Але рядок "CLIENT" з'являється в коді 937 разів ... звідки ви навіть починаєте шукати?

Проблема іграшки полягає в тому, що всі значення незвичайні і можна з впевненістю гарантувати їх унікальність у коді. Не "1" або "10", але "50 000". Не "клієнт" чи "звіт", а "SR008-04X".

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

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


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

4
Приклад не виходить з ладу, тому що це проблема з іграшками. Навколишній код завжди буде жахливим, оскільки ділові правила, які має виконувати програмне забезпечення, - жах . Спроба уникнути цього фундаментального виклику за допомогою механізмів управління правилами та DSL, і того, що часто є відкладанням програміста , тому що вирішення проблем з ЦС є більш приємним, ніж вирішення тонкощів податкових форм. Спроби досягти «витонченості» часто є дурними дорученнями, оскільки кінцевим завданням програмного забезпечення є моделювання складної катастрофи.
whatsisname

Правила ведення бізнесу можуть бути жахом, але це само по собі не є приводом для написання такого посереднього процесуального кодексу. (Я схильний погоджуватися з Пападімулісом, що простіше моделювати та підтримувати правила в коді, ніж у конфігурації. Я просто думаю, що це повинен бути кращий код.) Проблема DRY, яку я бачу, не є магічними числами, це повторюється if (...) { attachDocument(...); }.
Девід Молес

2

У цьому є кілька питань.

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

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

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

Крім того, що константа приватна, її не можна використовувати ніде в коді.

Потім складіть список усіх правил і застосуйте список.

Наступне питання - як поводитися з константами. 500000 може виглядати непомітним, але дуже уважно потрібно дотримуватися правильного перетворення. Якщо застосовується будь-яка арифметика з плаваючою точкою, вона може бути перетворена на 500 000,00001, тому порівняння з 500 000,00000 може не вдатися. Або ще гірше 500000 завжди працює за призначенням, але чомусь 565000 не вдається при перетворенні. Переконайтеся, що конверсія явна і зроблена вами, а не компілятором. Часто це робиться шляхом перетворення його на якийсь BigInteger або BigDecimal перед його використанням.


2

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

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

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

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

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


Це саме те, що я думав !!! Коли логіка заглиблена в код, як експерт із домену / тематики чи бізнес-користувач може бачити цінність та логіку, які використовуються, щоб переконатися у правильності та діагностувати поведінку системи? Одне, що робить конфігураційний файл - це зробити налаштування видимими . Повинні бути певні засоби для сприяння наочності ділових правил - навіть якщо це кодування робить "складніше". Я можу прийняти тонкий клас або набір класів, які виконують цю роботу, не змішуючи інших проблем - доти, поки бізнес-користувач має засоби для доступу та розуміння.
ErikE
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.