Небезпеки величезного монолітного застосування


20

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

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

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

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

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

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

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


7
Якщо сонце зійде занадто рано, Англія відпливе до моря.
Maxpm

1
Або тиск в ядрі Землі трохи підвищується.
StuperUser

1
@Maxpm Я бачу, що ти там робив ... xkcd.com/687
teto

3
@Maxpm: На щастя, наш додаток не їздить на сходах і заходах. Ми віримо, що принцеса Селестія не провалиться на своїй роботі.
СФ.

1
@rwong: 1. Пристрій зупинено для оновлення. Незважаючи на те, що оновлення буде оновлено на льоту, ми не хочемо будь-яких несподіваних результатів, якщо оновлення з будь-якої причини піде не так. 2. Одноядерний ARM9 з вбудованим Linux. Є другий, контролюючий процесор, що працює без ОС, перевіряючи, чи основний процесор виробляє здоровий вихід.
СФ.

Відповіді:


5

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

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

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


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

23

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

Ви самі це сказали - це цілком ремонтопридатність, добре модульована ...

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

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

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

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

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


16

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

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


2
Але це стосується обох можливих архітектур ...
SF.

3
Так, так ...
Роберт Харві

10
... і тому ця відповідь не додає нічого до обговорення, окрім сприяння тестуванню одиниць.
benzado

2
@benzado: Це, за сценарієм ОП, має надзвичайно важливе значення.
Роберт Харві

2
@ironcode: Подивіться на книгу на кшталт "Ефективна робота зі застарілим кодом". Перше, що він говорить у цій книзі - це "Якщо у вас вже немає набору тестових одиниць із високим покриттям коду, напишіть їх спочатку, перш ніж робити що-небудь інше ". Я б сказав, що поради тут є більш ніж актуальними, враховуючи, що ОП спеціально запитала "Які ще небезпеки я не помічала".
Роберт Харві

8

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

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

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

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

Примусовий збій при необхідності також простіший за допомогою монолітного виконуваного файлу.


1
+1, інженерія стосується компромісів, менші бінарні файли теж коштують
бензадо

+1 Я щиро погоджуюся. Немає конкретних причин, щоб гарантувати кілька виконуваних файлів. Комунікація та координація між виконуваними файлами має свою ціну.
Ерік Робертсон

+1: Якщо він не зламався, не виправляйте.
Боб Мерфі

1

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

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

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

Ви хочете мати хороші тести на місці, хоча.


1

В ідеалі відповідь - так. Наявність декількох бінарних файлів має потенціал зробити її стабільнішою ....

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

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

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


1

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

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

Внутрішня структура також простіша, коли ви можете просто викликати метод або читати змінну, а не говорити через сокети або спільну пам'ять.

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

Це, мабуть, це нелегке завдання.

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


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

0

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

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

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