Якщо класи "ResourceManager" вважаються поганими, які існують альтернативи?


19

Я чую суперечливі думки, такі як:

  • "Виділені класи менеджера майже ніколи не є правильним інженерним інструментом"
  • "Виділені класи менеджера - це (зараз) найкращий спосіб вижити великий проект із тисячами ресурсів"

Візьмемо класичний клас ResourceManager, який має такі функціональні можливості:

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

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

Тоді є аргумент «використовувати завод» або «називати це фабрикою». Моя проблема з цим полягає в тому, що так, це фабрика, але це також кеш і перезавантажувач (за відсутністю кращого слова). Називаючи це фабрикою, це не описує належним чином, і якщо я роблю це належним заводом, то де кешувати та перезавантажуватись реалізовуються?

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


3
Може, назвати це складом замість фабрики? : P
уповільненийкавіар

Відповіді:


9

Я думаю, питання не в тому, що це погана конструкція. Проблема полягає в тому, що ім'я "Менеджер" не є описом, як "Оновлення" та "Процес" та "Актор". Хтось, хто намагається зрозуміти цю систему, не є корисним, і це створює плутанину, якщо у вас коли-небудь є інші класи, які виконують якусь операцію над активами.

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

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

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

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


Розмежування AssetLoader / AssetCache - не погана ідея.
Том Даллінг

4

"Чи роблю це в одному місці, чи багато це роблю?"

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

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

Нарешті, кілька моментів, про які варто подумати:

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

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


PS Окрім звичних аргументів типу "Singletons are жахливі" (які страшенно догматичні), ви коли-небудь бачили хороший аргумент проти ResourceManagers? «Виділені класи менеджера майже ніколи не є правильним інструментом інженерії» - це зовсім не аргумент для цього конкретного випадку .

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