Орієнтація на об'єкт цінна саме тим, що виникають такі типи сценаріїв, і він дає вам інструменти для розумного проектування абстракцій, які дозволяють скласти складність.
Справжнє запитання тут полягає в тому, де ти складеш цю складність?
Тож дозвольте мені відійти на мить назад і поговорити про те, про яку «складність» я говорю тут. Ваша проблема (наскільки я це розумію; виправте мене, якщо я помиляюся) - це модель наполегливості, яка не є ефективно корисною моделлю для завдань, які потрібно виконати з даними. Це може бути ефективним і корисним для інших завдань, але не для ваших завдань.
То що робити, коли ми маємо дані, які не представляють гарної моделі для наших засобів?
Перекласти. Це єдине, що ти можеш зробити. Цей переклад - це «складність», про яку я згадуюсь вище. Тож тепер, коли ми приймаємо, що будемо перекладати модель, нам потрібно визначитися з кількома факторами.
Чи потрібно нам перекладати обидва напрямки? Чи будуть обидва напрямки перекладені однаково, як у:
(Tbl A, Tbll B) -> Obj X (читати)
Obj X -> (Tbl A, Tbll B) (записувати)
чи дії з вставки / оновлення / видалення являють собою інший тип об'єкта, таким чином, що ви читаєте дані як Obj X, але дані вставляються / оновлюються з Obj Y? Який із цих двох способів ви хочете пройти, або якщо неможливо оновити / вставити / видалити, є важливими факторами, де ви хочете перекласти.
Куди перекладаєте?
Назад до першого твердження, яке я зробив у цій відповіді; OO дозволяє вам інкапсулювати складність, і на що я тут згадуюсь, це те, що ви не тільки повинні, але й повинні інкапсулювати цю складність, якщо хочете переконатися, що вона не просочується і не проникає у весь ваш код. У той же час важливо визнати, що ви не можете мати ідеальну абстракцію, тому турбуйтеся про це менше, ніж про дуже ефективну та корисну.
Знову зараз; Ваша проблема полягає в тому, де ви ставите цю складність? Ну у вас є вибір.
Це можна зробити в базі даних, використовуючи збережені процедури. Це має недолік, що часто не дуже добре грає з ORM, але це не завжди так. Збережені процедури дозволяють отримати певні переваги, зокрема часто. Процедури, що зберігаються, але можуть вимагати великого обслуговування, але вам належить проаналізувати конкретний сценарій і сказати, чи буде обслуговування більш-менш інших варіантів. Я особисто дуже вмілий зі збереженими процедурами, і як такий факт наявного таланту зменшує накладні витрати; ніколи не варто недооцінювати значення прийняття рішень , заснованих на тому, що ви дійсно знаєте. Іноді субоптимальне рішення може бути більш оптимальним, ніж правильне рішення, оскільки ви або ваша команда знаєте, як створити та підтримувати його краще, ніж оптимальне рішення.
Ще один варіант в базі даних - це перегляди. Залежно від сервера вашої бази даних, вони можуть бути вкрай оптимальними або недооптимальними або взагалі не ефективними, один із недоліків може бути часом запитів залежно від того, які параметри індексації є у вашій базі даних. Перегляди стають ще кращим вибором, якщо вам ніколи не потрібно робити будь-які зміни (вставити / оновити / видалити).
Проходячи повз базу даних, у вас є старий режим очікування використання шаблону репозиторію. Це перевірений часом підхід, який може бути дуже ефективним. Недоліки, як правило, включають плиту котла, але добре зберігаються сховища можуть уникнути деякої кількості цього, і навіть коли це призводить до невдалої кількості плит котла, сховище має бути простим кодом, який легко зрозуміти та підтримувати, а також представляє хороший API / абстракція. Також сховища можуть бути корисними для їх перевірки одиниці, яку ви втрачаєте, використовуючи параметри в базі даних.
Існують такі інструменти, як автоматичний картограф , які можуть зробити використання ORM правдоподібним, коли вони можуть зробити переклад між базовою моделлю з orm на зручні моделі, але деякі з цих інструментів можуть бути складними, щоб підтримувати / розуміти, що вони більше схожі на магію; хоча вони створюють мінімум накладних кодів, що призводить до менших накладних витрат на технічне обслуговування, коли вони добре розуміються.
Далі ви крокуєте все далі і далі від бази даних , а це означає, що буде більше кількості коду, який буде мати справу з неперекладеною моделлю збереження, яка буде справді неприємною. У цих сценаріях ви говорите про введення шару перекладу у ваш інтерфейс користувача, який здається, що ви можете робити зараз. Це взагалі дуже погана ідея і з часом жахливо занепадає.
Тепер почнемо говорити божевільно .
Це Object
не єдине, що існує у всьому, абстракція. Протягом багатьох років, що вивчали інформатику, і ще до цього часу з вивчення математики, спостерігалося глибоке абстрагування. Якщо ми почнемо займатися творчістю, давайте поговоримо про відомі доступні абстракції, які вивчалися.
Там модель актора.Це цікавий підхід, оскільки він говорить, що все, що ви робите, - це надсилання повідомлень на інший код, який фактично делегує всю роботу тому іншому коду, що є дуже ефективним у захопленні складності від усього вашого коду. Це може спрацювати в тому випадку, якщо ви надсилаєте повідомлення акторові, що каже: "Мені потрібен Obj X, надісланий Y", і у вас є гніздо, яке чекає відповіді в місці Y, яке потім обробляє Obj X. Ви навіть можете надіслати повідомлення, яке вказує "Мені потрібні Obj X і обчислення Y, Z зроблено для цього", і тоді вам навіть не потрібно чекати; переклад відбувається на іншій стороні цього пропуску повідомлення, і ви можете просто рухатися далі, якщо вам не потрібно прочитати його результат. Це може бути незначним зловживанням акторською моделлю для ваших цілей, але все залежить;
Ще одна межа інкапсуляції - це межі процесу. Їх можна дуже ефективно використовувати для розмежування складності. Ви можете створити код перекладу як веб-службу, де спілкування є простим HTTP, використовуючи SOAP, REST або якщо ви дійсно хочете власний протокол (не пропонується). STOMP - це зовсім не поганий новий протокол. Або скористайтеся звичайною послугою демона із системою пам’яті, що оприлюднюється в локальній системі, для швидкого спілкування знову, використовуючи той обраний протокол. Це насправді має деякі непогані переваги:
- У вас може бути запущено декілька процесів, які одночасно виконують переклад для більш старшої та нової версій, що дозволяє оновити службу перекладу, щоб оприлюднити об'єктну модель V2, а потім окремо в подальшому оновити споживчий код для роботи з новим об'єктом модель.
- Ви можете робити такі цікаві речі, як закріплення процесу до ядра для продуктивності, ви також отримуєте певну безпеку безпеки в цьому підході, зробивши це єдиним процесом, який працює з привілеями безпеки для дотику до цих даних.
- Ви отримаєте дуже сильну межу, коли ви будете говорити про межі процесу, які залишатимуться фіксованими, забезпечуючи мінімальний витік вашої абстракції протягом тривалого часу, оскільки запис коду в просторі перекладу не можна буде викликати поза простором перекладу, оскільки вони не поділять обсяг процесу, забезпечуючи фіксований набір сценаріїв використання за контрактом.
- Можливість спрощення асинхронних / неблокуючих оновлень.
Недоліки, очевидно, більше обслуговування, ніж зазвичай, комунікаційні витрати впливають на продуктивність та обслуговування.
Існує велика різноманітність способів інкапсуляції складності, які дозволять розмістити цю складність у дедалі більш дивних та цікавих місцях вашої системи. Використовуючи форми функцій вищого порядку (часто їх підробляють, використовуючи шаблон стратегії або різні інші непарні форми об'єктних шаблонів), ви можете зробити дуже цікаві речі.
Правильно, почнемо говорити про монаду. Ви можете створити цей шар перекладу дуже незалежним чином з невеликих конкретних функцій, які роблять необхідні незалежні переклади, але приховати всі ці функції перекладу далеко не видно, тому вони навряд чи доступні для зовнішнього коду. Це має перевагу зменшення надійності на них, що дозволяє їм легко змінюватися, не впливаючи на зовнішній код. Потім ви створюєте клас, який приймає функції вищого порядку (анонімні функції, лямбда-функції, об'єкти стратегії, однак вам потрібно їх структурувати), які працюють на будь-якому з приємних об'єктів типу OO. Потім ви дозволяєте базовому коду, який приймає ці функції, виконувати буквальне виконання, використовуючи відповідні методи перекладу.
Це створює межу, коли весь переклад існує не лише з іншого боку кордону, далеко від усього вашого коду; він використовується лише на тій стороні, що дозволяє решті коду навіть нічого про нього не знати, окрім місця входу для цієї межі.
Гаразд, так, це справді говорить божевільно, але хто знає; ви можете просто бути таким божевільним (якщо серйозно, не вживайте монадів з божевільністю нижче 88%, існує реальний ризик тілесних ушкоджень).