Чи планував Дайкстра проводити модуляцію коду, коли писав про розділення проблем?


9

По-перше, я прочитав уривок статті Едсгера У. Дійкстри 1974 року "Про роль наукової думки":

Дозвольте спробувати пояснити вам, що на мій смак характерне для всього розумного мислення. Це полягає в тому, що хтось готовий поглиблено вивчити аспект предмета своєї людини ізольовано заради власної послідовності, увесь час знаючи, що людина займається лише одним із аспектів. Ми знаємо, що програма повинна бути правильною, і ми можемо вивчати її лише з цієї точки зору; ми також знаємо, що це повинно бути ефективним, і ми можемо вивчити його ефективність в інший день, так би мовити. В іншому настрої ми можемо запитати себе, і якщо так: чому, програма бажана. Але нічого не отримується - навпаки! - одночасно вирішуючи ці різні аспекти. Це те, що я іноді називаю "відокремленням проблем", яке, навіть якщо не цілком можливо, поки що є єдиною доступною технікою ефективного упорядкування думок, про яку я знаю. Це те, що я маю на увазі під "зосередженням уваги на якомусь аспекті": це не означає ігнорування інших аспектів, це просто справедливість у тому, що з точки зору цього аспекту, інше не має значення. Це однозначне та багатоколірне налаштування одночасно.

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

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

Короткий приклад, ось код, який має доступ до даних та перегляд (вихід):

$sql = "SELECT * FROM product WHERE id = " . db_input($id);
$row = db_fetch_array(db_query($sql)); 
<option value="<?=$row['id']?>"<?= $row['ver'] == $row['ver'] ? '  selected="selected"' : '' ?>>Version <?=$row['ver']?></option>

Використовуючи сучасний OO, я міг розмістити доступ до даних у своєму власному файлі за допомогою шаблону сховища, код View може перейти до власного шаблону файлу, і я можу з'єднати їх разом для спілкування через контролер (або Action або Request Handler), і я можу додайте фабрику для створення та підключення різних залежностей. І я можу мати файл конфігурації, який визначає ці заводи. Звичайно, це крок від єдиного файлу.

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

Чому тоді ми обтяжуємо себе фізичним модульним розділенням коду та моделями дизайну? Чи буде недостатньо просто зосередитись на аспекті, незалежно від того, як структурований ваш код?

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

Чи повинен розлучення проблем залишатися розумовою вправою, а не фізичною?
Іншими словами, чи повинен бути розрив між психічним (фокус на) та фізичним (кодом на папері) аспектами програмування?


5
Я майже впевнений, що до 1974 року він просто розглядав модульне програмування як очевидну задачу, і саме тому він прямо не обговорював це в цій статті. Документ Парнаса про те, як проводити модуляцію, був у 1972 році, і до того часу, чи про модуляризацію це вже не було питання. Насправді, те, що ви описуєте, навіть не є модульним програмуванням, це структуроване програмування , що сам Дійкстра настійно аргументував на користь вже в 1968 р. У своїй класичній роботі «Іди вважати шкідливою».
Йорг W Міттаг

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

@ JörgWMittag, чи можете ви визначити відмінність між структурованим та модульним програмуванням? Деякі посилання на google припускають, що вони однакові.
Денніс

Структуровані = IF, WHILE, FORа GOTO. Модульний = модулі з чітко визначеним загальнодоступним API, чітко відокремлений від прихованої внутрішньої реалізації та подання. (Наприклад Modula, Mesa, Modula-2, Modula-3, пізніші діалекти Паскаля ( UNIT).)
Jörg W

Відповіді:


2

Дайкстра робить чітке твердження про те, як думати. Модуляризація програми (і процесу) - і це бажано - можливо, є результатом такого мислення, але ключовим моментом він є те, як оцінити проблему. Програма, як правило, є вирішенням проблеми, і, виступаючи за "розділення проблем", він пропонує мудрі поради. Найкращим прикладом цього є, мабуть, «оптимізація». Жарт був такий: "Плануючи оптимізувати програму, вашою першою стратегією має бути: Не." Іншими словами, ви хочете зосередитись на тому, щоб спочатку зробити програму правильною. Зробити це швидким і фантазійним - це питання, яке слід розділити, але також не повністю усунути.


14

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

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


9

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

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


5
Я думаю, що слід зазначити, що значна частина сучасної думки про розділення концернів виходила з ранніх статей, які зрештою породили орієнтоване на аспекти програмування від IBM. Я думаю, що початкові документи (кінець 90-х - початок 2000-х) є найбільшим впливом на це. Минув час, і веб-сайти все змінилися. Не впевнений, чи зможу я їх ще раз знайти.
Берін Лорич

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

1
Це дійсно допомогло б нам зрозуміти вашу позицію, якби ви (а) пояснили, що, на вашу думку, має на увазі Дайкстра під "розділенням проблем" та (б) поясніть ЧОМУ ви вважаєте, що те, що він мав на увазі, вже не має значення.
Джон Р. Стром

2

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

  1. Спочатку я розглядаю дані. Дані представляють логічні предикати проблеми. Класи побудовані для абстрактних сутностей у реальному світі, а їх атрибутами є параметри абстракції. Асоціації між класами представляють функціональні відображення між екземплярами класу. На даний момент немає коду, що бере участь у мисленні, і поняття про будь-яку обробку. Просто статичний погляд на логіку, що бере участь у предметі.
  2. По-друге, я розглядаю динаміку. Будь-який клас, який має нетривіальний життєвий цикл, моделюється як машина з кінцевим станом. Це передбачає міркування виконання послідовності та синхронізації. Знову ж таки, жоден код не працює, як взаємодія і послідовність дій.
  3. По-третє, я вважаю обробку. Тут реальна алгоритмічна робота, яку необхідно виконати при переходах стану або в інших синхронних операціях.

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

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


1

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

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

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

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


-1

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

Слід керуватися принципами SOLID при розробці використання ОО. Ось приємне посилання для них, але, TLDR про "розмежування проблем" здебільшого є S у SOLID: Принцип єдиної відповідальності або SRP.

Це, безумовно, фізичні вправи, а не розумові. Для вашого конкретного прикладу, MVC (або це брати і сестри MVVM та MVP) спрямовує фізично розділити концерти Model, View та Controller / Presenter / ViewModel на окремі файли. Я бачив деякі реалізації MVVM, де вони реалізовані в окремі збірки, щоб ще більше стримувати тенденцію до "змішування понять".

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

Потрібно також розглянути джерело вимог до будь-якого конкретного елемента ОО. Якщо ви змішуєте, скажімо, те, що хоче Клієнт із тим, що хоче Операційний персонал, ви також порушуєте SRP. Або, якщо говорити дядько Боб: Клас повинен мати одну і лише одну причину для зміни.

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


Ні. Принципи SOLID настільки відірвані від реальності фактично написання коду (= філософського), що їх можна зрозуміти лише будь-яким віддаленим корисним способом, тільки коли ви вже вмієте писати хороший код, і тоді вони в кращому випадку є зайвими. Використання їх як керівних принципів, не маючи вже досвіду та здібностей, дає надзвичайно поганий код.
jpmc26
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.