Коли клас або модуль повинен знаходитися в окремому складі / DLL?


22

Чи є якісь вказівки щодо вирішення, коли клас повинен бути у власній збірці / DLL? Я часто бачу дві школи думки:

1) Кожне "групування" класів належить до власних DLL, наприклад, сховищ, служб, DTO, інфраструктури тощо.

2) Все повинно бути в одній DLL, але відокремлено через простори імен / папок, наприклад, DLL "Core" з додатковими просторами імен, наприклад, Core.Repositories, Core.Services, Core.DTO тощо.

На роботі ми просто збиваємо все в одній асамблеї під назвою "Бізнес". Є кілька папок, але реального розділення немає - об'єкти бізнесу (за логікою, деякі з яких навіть не повинні бути класами) без побоювання збираються в папку "BusinessObjects". Речі, що використовуються в більш ніж одному класі, знаходяться в папці "Core". Утиліти знаходяться в папці "Утиліти", інфраструктура доступу до даних - це папка "Дані" - ви отримуєте ідею.

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

Відповіді:


12

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

Наприклад, виходячи з того, що ви згадали, у мене обов'язково були б такі проекти:

  • Основні
  • Дані
  • Домен (або BusinessObjects)
  • Послуги
  • Утиліти (або помічники)

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

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

Легко зловживати запропонованими рішеннями (тобто занадто багато проектів або занадто мало). Пошук хорошого балансу, коли слід пам’ятати про багаторазове використання та низьке з'єднання, повинно призвести до чогось більш перевіреного та ремонтопридатного.
Бернард

16

"Дядько Боб" Мартін з "Чистого кодексу", слава "Принципи твердих принципів" тут окреслила три принципи :

  • Принцип еквівалентності повторного використання: гранули повторного використання - це гранули вивільнення.
  • Загальний принцип закриття: Класи, що змінюються разом, пакуються разом.
  • Загальний принцип повторного використання: Класи, які використовуються разом, упаковуються разом.

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


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

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

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

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

1
Вибачте, але що саме в цьому є "абсолютно випадковим і не обґрунтованим"? Цю відповідь я опублікував після багатьох років роботи над рішеннями, які були розбиті на набагато більше проектів, ніж це потрібно з будь-якої іншої причини, окрім того, як ви це робите. Результат? Льодовикові часи складання та загроза пекла залежності (особливо в добу NuGet). Розбиття речей на окремі збори має вартість, і якщо немає користі для компенсації цієї вартості, то це лише викрадення бізнесу.
варення

4

Деякі інші керівні принципи, з якими я працюю:

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

  • Ви хочете мати змогу змінювати / розгортати цей код без повторної розстановки / перекомпіляції всього проекту? Іноді корисно було просто відновити модуль, розгорнути та перезапустити веб-додаток.

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


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