Змінна відповідальність патерну Репозиторій

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

Що не так з репозиторієм? Очевидно, що з самим паттерном все нормально, але різниця в його розумінні розробниками. Я спробував дослідити це і натрапив на два основні моменти, які, на мій погляд, є причиною різного відношення до нього. Одним з них є «змінна» відповідальність репозиторію, а інший пов'язаний із недооцінкою unit testing. Під катом я поясню перший.

Змінна Відповідальність Репозиторію

Коли мова заходить про побудову архітектури у всіх в голові відразу виникає уявлення про трьох шарів: шар представлення (Presentation Layer), бізнес-логіки (Business Layer) і шар даних (Data Layer) (см MSDN). У таких системах об'єкти бізнес логіки використовують репозиторії для отримання даних з фізичних сховищ. Репозиторії повертають бізнес-сутності замість сирих рекордсетов. Дуже часто це обгрунтовується тим, що якщо б нам потрібно було замінити тип фізичного сховища (база, файл або сервіс), то ми зробили б абстрактний клас репозиторію і реалізували б специфічний для потрібного нам сховища. Виглядає приблизно так:

image

Про таке ж поділ говорить Мартін Фаулер і MSDN. Як правило, опис — це, всього лише, спрощена модель. Тому, хоча це виглядає правильно для невеликого проекту, це вводить в оману, коли ви намагаєтеся перенести цей патерн на більш складний. Існуючі ORM ще сильніше збивають з пантелику, оскільки реалізують багато речей з коробки. Але уявімо, що розробник знає тільки як використовувати Entity Framework (або інший ORM) тільки для отримання даних. Куди, наприклад, він повинен помістити кеш другого рівня, або логування всіх бізнес-операцій? У спробі зробити це, очевидно, що він будемо намагатися розділити модулі по функціоналу, іду SPR з SOLID, і побудувати з них композицію, яка, можливо, буде виглядати так:

image

Виконує репозиторій ту ж роль, що і раніше? Очевидна відповідь «НІ», так як тепер він не витягує дані з сховища. Ця відповідальність була перенесена в інший об'єкт. На цьому ґрунті виникає перша нестиковка між таборами абстракціоністів і конкретистов.

Замість аналізу

Якщо взяти за правило, що всі терміни повинна зберігати своє значення незалежно від модифікацій коду, то було б правильно на першому етапі не називати репозиторієм об'єкт, який просто повертає дані. Це DAO патерн чистої води, оскільки його завдання заховати конкретний інтерфейс доступу до даних (ling, ADO.NET, або щось ще). У той же час репозиторій може не знати про такі деталі взагалі нічого, збираючи в єдину композицію всі підсистеми доступу до даних.

Чи вважаєте ви, що така проблема існує?
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.