Чи відповідає схема ActiveRecord / заохочує принципи дизайну SOLID?


43

Мене цікавить, чи заохочує або відлякує використання принципів дизайну SOLID дизайн ActiveRecord, відомий з Ruby on Rails .

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


6
В кінці своєї розмови SOLID Ruby на конференції Ruby 2009 Джим Вейріх запитує присутніх: "Об'єкти ActiveRecord реалізують концепцію домену та концепцію постійності. Чи це порушує SRP (єдиний принцип відповідальності)?" Аудиторія погоджується, що вона порушує СРП. Джим запитує, чи це їх турбує. Багато членів аудиторії кажуть так. Чому? Це ускладнює тестування. Це робить об'єкт стійкості набагато важчим.
Девід Дж.

Відповіді:


56

На ActiveRecord є певна вагома критика. Як завжди, дядько Боб підсумовує це ідеально :

Проблема, яку я маю з Active Record, полягає в тому, що вона створює плутанину щодо цих двох дуже різних стилів програмування. Таблиця бази даних - це структура даних. Він виявив дані і жодної поведінки. Але, як видається, об'єктом є активний запис. У ньому є "приховані" дані та виявлена ​​поведінка. Я вкладаю слово "прихований" у лапки, тому що дані насправді не приховані. Практично всі похідні ActiveRecord експортують стовпці баз даних через аксесуари та мутатори. Дійсно, активний запис призначений використовуватись як структура даних.

З іншого боку, багато людей ставлять методи бізнес-правил у своїх класах Active Record; через що вони здаються об'єктами. Це призводить до дилеми. На яку сторону рядка дійсно падає активний запис? Це об’єкт? Або це структура даних?

Вікіпедія підсумовує критику за занепокоєння :

У ООП концепція інкапсуляції часто суперечить концепції розділення проблем. Взагалі кажучи, моделі, що сприяють розділенню проблем, більше підходять для ізольованих одиничних тестів, тоді як моделі, що сприяють інкапсуляції, мають більш прості у використанні API. Active Record дуже сприяє інкапсуляції до того моменту, коли тестування без бази даних є досить важким.

Спеціально для реалізації Ruby on Rails Гевін Кінг пише (моє наголос):

На даний момент більшість розробників думають, що ж, гаразд, то як я, мабуть, повинен знати, які атрибути має компанія, дивлячись на мій код? І як мій IDE може автоматично заповнити їх? Звичайно, люди з Rails мають швидку відповідь на це питання. О, просто запустити клієнта бази даних і зазирнути у базу даних !. Тоді, припускаючи, що ви знаєте правила автоматичної капіталізації та плюралізації ActiveRecord / ідеально /, ви зможете відгадати назви атрибутів власного класу компанії та ввести їх вручну.

Також про реалізацію Ruby on Rails Джон Янущак пише (моє наголос):

ПРОБЛЕМА №1: СТАТИЧНІ МЕТОДИ

...

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

ПРОБЛЕМА №2: НАСТРОЙКИ ГЛОБАЛЬНОЇ КОНФІГУРАЦІЇ

...

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

Ще кілька ресурсів про те, чому ActiveRecord та ORM взагалі вважаються антидієграми:

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


ВАЖЛИВЕ оновлення для рейок 5+: "І як мій IDE може автоматично заповнити їх? Звичайно, люди з Rails мають швидку відповідь на це питання. О, просто запустити клієнта бази даних і зазирнути в базу даних!" Неправильно більше. За допомогою API атрибутів ви можете визначити всі доступні стовпці на моделі
Filip Bartuzi

6

(Я припускаю, що клас ActiveRecord реалізований без будь-якої можливості для введення залежності).

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

Отже, ActiveRecord в значній мірі протистоїть SRP і створює певний головний біль у підтримці; здається, це забирає владу писати одиничні тести.

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