Для мене це проблема зчеплення і пов'язана з деталізацією конструкції. Навіть найслабша форма сполучення вводить залежності від однієї речі до іншої. Якщо це зроблено для сотень до тисяч об'єктів, навіть якщо всі вони відносно прості, дотримуються SRP, і навіть якщо всі залежності протікають до стійких абстракцій, це дає базу коду, яку дуже важко обґрунтувати як взаємопов'язане ціле.
Є практичні речі, які допомагають вам оцінити складність бази коду, яку не часто обговорюють в теоретичній SE, як, наскільки глибоко в стек викликів ви можете потрапити до того, як досягти мети, і наскільки глибоко вам потрібно пройти, перш ніж зможете, з великою довірою розумійте всі можливі побічні ефекти, які можуть виникнути на цьому рівні стека викликів, у тому числі у випадку винятку.
І я виявив, що, на моєму досвіді, міркувати про те, що більш плоскі системи з дрібнішими стеками викликів мають набагато простіше. Крайнім прикладом може бути система-компонент сутності, де компоненти - це лише необроблені дані. Тільки системи мають функціональні можливості, і в процесі впровадження та використання ECS я вважав, що це найпростіша система, коли-небудь, міркувати про те, коли складні бази даних, що охоплюють сотні тисяч рядків коду, в основному кипіть до кількох десятків систем, які містять усю функціональність.
Занадто багато речей забезпечують функціональність
Альтернативою раніше, коли я працював у попередніх кодових базах, була система з сотнями до тисяч в основному крихітних об'єктів на відміну від кількох десятків об'ємних систем, де деякі об'єкти використовувались просто для передачі повідомлень від одного об’єкта до іншого ( Message
об'єкта, наприклад, який мав свою власний публічний інтерфейс). Це, головним чином, те, що ви отримуєте аналогічно, повертаючи ECS назад до точки, де компоненти мають функціональні можливості, і кожна унікальна комбінація компонентів в об'єкті дає свій власний тип об'єкта. І це, як правило, дає менші, простіші функції, успадковані та надані нескінченними комбінаціями об'єктів, що моделюють маленькі ідеї ( Particle
object vs.Physics System
, наприклад). Однак він також має тенденцію отримати складний графік взаємозалежностей, що ускладнює міркування про те, що відбувається з широкого рівня, просто тому, що в кодовій базі є так багато речей, які насправді можуть щось зробити, а тому можуть зробити щось не так - - типи, які не є типом "даних", а "об'єктними" типами з пов'язаною функціональністю. Типи, які служать чистими даними без пов’язаних функціональних можливостей, не можуть зійти з ладу, оскільки нічого не можуть зробити самостійно.
Чисті інтерфейси не дуже допомагають цій проблемі зрозумілості, тому що навіть якщо це робить "залежність від часу компіляції" менш складною та надає більше місця для дихання для змін та розширення, це не робить "залежності часу виконання" та взаємодії менш складними. Клієнтський об’єкт все ще закінчує викликом функцій конкретного об'єкта акаунта, навіть якщо вони викликаються через IAccount
. Поліморфізм та абстрактні інтерфейси мають свою користь, але вони не розв'язують речі таким чином, що справді допомагає вам обґрунтувати всі побічні ефекти, які можуть тривати в будь-який момент. Щоб досягти цього типу ефективної розв'язки, вам потрібна база коду, яка має набагато менше речей, що містять функціональні можливості.
Більше даних, менша функціональність
Тож я знайшов підхід ECS, навіть якщо ви не застосовуєте його повністю, як надзвичайно корисний, оскільки він перетворює те, що було б сотні об'єктів, просто необробленими даними з об'ємними системами, більш грубо розробленими, що забезпечують усі функціональність. Це максимально збільшує кількість типів "даних" і мінімізує кількість типів "об'єкт", а отже, абсолютно мінімізує кількість місць у вашій системі, що може насправді піти не так. Кінцевим результатом є дуже "плоска" система без складного графіка залежностей, просто системи до компонентів, ніколи навпаки і ніколи не компоненти до інших компонентів. Це в основному набагато більше необроблених даних і набагато менше абстракцій, що призводить до централізації та згладжування функціональності бази даних коду до ключових областей, ключових абстракцій.
30 простих речей не обов’язково простіше міркувати про більш ніж 1 складнішу річ, якщо ці 30 простіших речей взаємопов'язані, тоді як складна річ стоїть сама по собі. Отже, моя пропозиція насправді перенести складність від взаємодії між об'єктами і більше на більш об'ємні об'єкти, які не повинні взаємодіяти ні з чим іншим, щоб досягти масової розв'язки, на цілі "системи" (не моноліти та об'єкти бога, пам'ятайте, і не класи з 200 методами, але щось значно вищий рівень, ніж a Message
чи a, Particle
незважаючи на мінімалістичний інтерфейс). І віддайте перевагу більш простим старим типам даних. Чим більше ви залежите від них, тим менше зчеплення ви отримаєте. Навіть якщо це суперечить деяким ідеям SE, я виявив, що це дуже багато допомагає.