Брехня 2: Код повинен бути розроблений навколо моделі світу? [зачинено]


23

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

(ЛЖ № 2) КОД повинен бути спроектований у всьому світі МОДЕЛЮ СВІТУ

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

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

Ось мої проблеми з цією брехнею зокрема.

  1. Цінність коду є моделлю / картою уявного світу, оскільки моделювання уявного світу допомагає (принаймні мені, особисто) уявити і впорядкувати код.

  2. Наявність класу "Ракета" - для мене абсолютно правильний вибір для класу. Можливо, "Ракети" можуть бути розбиті на такі типи Ракет, як AGM-114 Hellfire і т.д., які містили б силу корисного навантаження, максимальну швидкість, максимальний радіус повороту, тип націлювання тощо, але все ж кожна вистрілена ракета повинна мати позицію і швидкість.

  3. Звичайно, 100 ракет коштує більше, ніж 1 ракета. Якщо на екрані є 100 ракет, для оновлення їх позиції повинно бути 100 різних обчислень. Другий абзац звучить так, ніби він стверджує, що якщо є 100 Ракет, для оновлення стану потрібно коштувати менше 100 обчислень?

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


9
@gnat: Це питання прямо входить до провінції дизайну програмного забезпечення, тому я схильний дати йому деяку свободу.
Роберт Харві

12
Цей запис у блозі написаний досить погано, і він не надто добре захищає та підтримує свої претензії. Я б не задумувався над цим.
whatsisname

21
Хто б не написав цю цитату, це ідіот, який мало розуміє поняття ОО або того, як вони реалізовані в програмному забезпеченні. По-перше, ми не відображаємо уявний світ, ми відображаємо реальний світ. І якщо у вас є 100 ракет, тільки стан додаткових ракет використовує додаткові ресурси, а не модель чи поведінку. Він, схоже, має про це різні ідеї і пропонує виправити проблему, якої не існує. "Групування подібних речей" як оптимізація може мати сенс іноді, але абсолютно не залежить від використання класів чи ні. Якщо ви хочете навчитися, уникайте цього шарлатана.
Мартін Мейт

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

9
Я думаю, що то, що він отримує, - чи справді вам потрібно 100 [ймовірно, динамічно розподілених також віртуальних методів]? Перелік швидкостей означає, що ви можете використовувати векторні інструкції, щоб додати швидкість до позиції на кожному оновленні галочки, а не писати наївну петлю через список об’єктів)
Random832

Відповіді:


63

По-перше, давайте подивимось на якийсь контекст: це ігровий дизайнер, який пише в блозі, тема якого виводить останню крапку роботи від процесора Cell BE. Іншими словами: мова йде про програмування консольних ігор, а точніше консольне програмування ігор для PlayStation 3.

Тепер ігрові програмісти - це цікавий куточок, тим більше консольні ігрові програмісти, а Cell BE - досить дивний процесор. (Є причина, чому Sony почала використовувати більш звичайний дизайн для PlayStation 4!)

Отже, ми повинні дивитися на ці твердження в цьому контексті.

У цій публікації блогу також є деякі спрощення. Зокрема, ця брехня №2 представлена ​​погано.

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

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

Наведу приклад, який я вже давав у деяких інших відповідях за ці роки, (невідомий приклад Введення до OO 101). Ось як виглядає банківський рахунок майже в кожному класі OO коли-небудь:

class Account {
  var balance: Decimal
  def transfer(amount: Decimal, target: Account) = {
    balance -= amount
    target.balance += amount
  }
}

Отже: balanceце дані , і transferце операція .

Але! Ось як виглядає банківський рахунок майже в кожному банківському програмному забезпеченні коли-небудь:

class TransactionSlip {
  val transfer(amount: Decimal, from: Account, to: Account)
}

class Account {
  def balance = 
    TransactionLog.filter(t => t.to == this).map(_.amount).sum - 
    TransactionLog.filter(t => t.from == this).map(_.amount).sum
}

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

Зауважте, що обидва ці моделі. І те і інше однаково справедливі. І те й інше правильно. Обидві ці моделі одне і те ж. І все-таки вони абсолютно подвійні один одному: все, що є даними в одній моделі, - це операція в іншій моделі, і все, що є операцією в одній моделі, - це дані в іншій моделі.

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

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

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

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


1
Чи це не означатиме, що хороший код моделює реальний світ, і що насправді це лише нерозуміння реального світу, що спричиняє погану модель і, отже, поганий код?
yitzih

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

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

@yitzih: кожна модель є абстракцією та спрощенням, тому ви можете звинуватити кожну модель у неправильній, але це не конструктивно. Кожна модель повинна виконувати мету і повинна бути достатньо хорошою для цього, не витрачаючи ресурсів на непотрібні речі. Що стосується програмного забезпечення уряду, людина може бути людиною, яка може брати участь у виборах, повинна сплачувати податки або може бути одружена з іншою людиною, для нашого програмного забезпечення для управління CRM, людина - це людина, яка асоціюється із замовленнями та має адресу доставки (і ні моделює, як він їсть)…
Холгер

2
Якщо людина знає щось про банківську діяльність, то другому буде простіше, а оскільки банківські методи, про які вони знають, були винайдені для того, щоб банківська робота працювала, вони можуть зробити банківське програмне забезпечення, яке працює. Не тому, що друга модель «більше схожа на реальний світ», а тому, що вона описує кращий банк. Перша модель може бути однаково точним представленням реального дисфункціонального банку! Здогадайтесь, що: якщо ви хочете гарного банківського програмного забезпечення, тоді програмістам потрібно навчитися робити банківські справи добре, хоч би лише з вимог документів.
Стів Джессоп

19

Я не погоджуюся з кожною «брехнею», яку він пропонує.

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

Брехня №1 - Великі питання щодо масштабування. Нікого не хвилює, якщо крихітна програма займає довший час, який є єдиним значенням постійних часу, вони піклуються про те, щоб при подвоєнні вводу розмір не збільшив час виконання на 10.

Брехня №2 - Моделювання програм після реального світу дозволяє програмісту дивитись на ваш код через 3 роки, щоб легко зрозуміти, що він робить. Код повинен бути бездоганним, або вам доведеться витратити години, намагаючись зрозуміти, що програма намагається зробити. Інша відповідь підказує, що у вас може бути більше загальних класів, як LaunchPadі MassiveDeviceMover. Це не обов'язково поганий клас, щоб мати, але вам все одно знадобиться Rocketклас. Як хтось повинен знати, що MassiveDeviceMoverробить або що рухається? Це рухомі гори, космічні кораблі чи планети? Це в основному означає, що додавання до таких класів MassiveDeviceMoverробить вашу програму менш ефективною (але, можливо, способом більш зрозумілим і зрозумілим).

Додатково вартість часу розробника почала перевищувати вартість апаратних засобів давно. Жахлива ідея починати намагатися розробити з оптимізацією в передній частині ваших думок. Ви програмуєте його легко і зрозуміло, а потім налаштовуйте програму, дізнавшись, які частини ваших програм займають багато часу для запуску. Не забувайте: 80% часу на виконання використовується 20% програми.

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


5
Я думаю, що я більше співчуваю №3. За 30 років програмування переважна більшість помилок, проблем з продуктивністю та інших проблем, які я бачив, були вирішені шляхом виправлення подання даних. Якщо дані вірні, код практично пише сам.
Лі Даніел Крокер

6
Справжня проблема з №3 полягає в тому, що він порівнює яблука з апельсинами, а не той код важливіший, ніж дані або навпаки.
Doc Brown

3
Вхідні дані не з ваших рук, але те, як представити дані у вашому програмному забезпеченні, повністю залежить від них. Ви можете називати цю частину "кодування", але я думаю, що це не так: наприклад, вона часто не залежить від мови і часто робиться до початку кодування. Я згоден, однак, що код, який очищає некрасиві вхідні дані, часто є хорошою справою; але ви не можете цього робити, поки у вас не буде визначення "чистого".
Лі Даніел Крокер

3
Я взагалі не думаю, що брехня №3 - це брехня. Фред Брукс вже писав десятиліття тому: "Покажіть мені свої блок-схеми і приховуйте свої таблиці, і я буду продовжувати таємницю. Покажіть мені свої таблиці, і зазвичай мені не потрібні ваші блок-схеми; вони будуть очевидними". (Сьогодні ми, мабуть, говорили б про "алгоритми" та "типи даних" або "схеми".) Отже, важливість даних давно відома.
Йорг W Міттаг

1
@djechlin Моя думка не в тому, що дані не важливі або що код важливіший. Просто дані не важливіші за код. Вони обидва дуже важливі і сильно покладаються один на одного.
yitzih

6

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

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

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


5

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

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

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

Яка альтернатива?

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

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


1
+1: Протоколи є дуже «реальним світом» абстракцією. Навіть у сучасному світі, протоколи, наприклад, одні з найважливіших працівників штату для візиту до держави. Хто перший йде на червоній доріжці під час зустрічі G8, Обама чи Путін? Вони обіймають чи потискають руки? Як я вітаю араба проти індіанця? І так далі. У нас є багато "речей" у "реальному світі", які не є "речами" у "фізичному світі". Моделювання реального світу не означає моделювання фізичного світу. Навіть якщо Rocketв коді цього хлопця немає типу, я готовий обміняти, що все-таки є якась модель…
Jörg W Mittag

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

Алан Кей уявив Dynabook як комп’ютер, який буде відданий дітям при народженні, і це стане продовженням їхнього мозку. Призначенням схеми MVC було б мати можливість перегляду та контролера подолати проміжок між мозку та Моделі для підтримки метафори прямого маніпулювання, тобто ілюзії, що комп'ютер - це лише розширення мозку, і що можна безпосередньо маніпулювати Модельними об’єктами своїми думками. І саме це ми маємо на увазі, коли говоримо, що Модель домену моделює "реальний світ". Він повинен реалізовувати абстракції в нашому мозку.
Йорг W Міттаг

І коли я замислююся про двигун фізичної консольної гри, то, мабуть, я справді не замислююся про ракети, і, отже, у моєму коді не повинно бути моделі ракети. Але я , напевно , думає деякі інші «реальний світ думки», і там повинні бути моделі тих , в коді.
Йорг W Міттаг

2

Альтернативою є моделювання речей, які хвилюють ваші програми. Навіть якщо ваша програма займається ракетами, вам, можливо, не потрібно мати сутність, яку називають a Rocket. Наприклад, у вас може бути LaunchPadсутність та LaunchScheduleсутність та MassiveDeviceMoverсутність. Те, що все це допомагає запускати ракети, не означає, що ви керуєте ракетами самі.


0

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

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

По-перше, я не назвав би це неправдою, як загальною помилкою. Називати це брехнею - це просто галас.

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

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

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

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

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


-1

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

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

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

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


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

@ user889742 Га! Правда. Ви точно заявили, що архітектурні проблеми архітектори намагаються вирішити протягом усього часу, і що робить галузь таким цікавим простором для роботи.
Ціна Джонса

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

-1

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

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