Відповіді:
DAO
є абстрагуванням збереження даних .
Repository
це абстракція колекції предметів .
DAO
буде розглядатися ближче до бази даних, часто орієнтованої на таблицю.
Repository
буде розглядатися ближче до Домену, що має справу лише в агрегованих коренях.
Repository
може бути реалізований за допомогою DAO
's, але ви не зробите навпаки.
Також, a, Repository
як правило, вужчий інтерфейс. Це повинно бути просто набір об'єктів, з Get(id)
, Find(ISpecification)
, Add(Entity)
.
Метод на зразок Update
підходить для a DAO
, але не a Repository
- при використанні a Repository
, зміни об'єктів зазвичай відслідковуються окремим UnitOfWork.
Здається, звичайним є Repository
те, що реалізація називається a, яка насправді більше a DAO
, і тому я думаю, що між ними є певна плутанина.
Гаразд, думаю, я можу краще пояснити, що я виклав у коментарях :). Таким чином, в основному ви можете бачити обидва ці ж, хоча DAO є більш гнучким, ніж сховище. Якщо ви хочете використовувати обидва, ви б використали сховище у своїх DAO. Я поясню кожен з них нижче:
Це сховище певного типу об’єктів - воно дозволяє шукати певний тип об’єктів, а також зберігати їх. Зазвичай він буде ОБЕРЕЖНО обробляти один тип об'єктів. Наприклад , AppleRepository
дозволить вам робити AppleRepository.findAll(criteria)
або AppleRepository.save(juicyApple)
. Зауважте, що репозиторій використовує терміни доменної моделі (не терміни БД - нічого, що стосується того, як дані зберігаються де-небудь).
Сховище, швидше за все, зберігатиме всі дані в одній таблиці, тоді як для цього шаблону цього не потрібно. Той факт, що він обробляє лише один тип даних, робить його логічно підключеним до однієї основної таблиці (якщо вона використовується для збереження БД).
DAO - це клас, який локалізує дані для вас (це здебільшого пошук, але він також використовується для зберігання даних). Шаблон не обмежує зберігання даних одного типу, тому ви можете легко мати DAO, який знаходить / зберігає пов'язані об'єкти.
Наприклад, ви можете легко мати UserDao, який розкриває такі методи
Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)
Усі вони пов'язані з Користувачем (та безпекою) і можуть бути вказані під тим самим DAO. Це не стосується сховища.
Зауважте, що обидва шаблони дійсно означають однакове (вони зберігають дані, і вони абстрагують доступ до них, і обидва вони виражені ближче до доменної моделі і навряд чи містять посилання на БД), але спосіб їх використання може дещо відрізнятися, тому що DAO трохи більш гнучким / загальним, тоді як Репозиторій трохи більш специфічний і обмежує лише тип.
CarDescription
, наприклад, language_id
як зовнішній ключ - тоді я можу зробити щось подібне: CarRepository.getAll(new Criteria(carOwner.id, language.id));
що дало б мені всі машини мовою певної мови - це правильний спосіб зробити це ?
CarRepository.findByLanguageId(language.id)
і вам навіть не потрібно буде писати код, ви просто визначите інтерфейс методом з цим ім'ям, і Spring Data піклується про те, щоб створити для вас реалізацію класу за замовчуванням. Досить акуратні речі;)
findById
). І ви практично зробили. Тоді, що робить Spring Data, це те, що вони знаходять усі створені вами інтерфейси, які розширюють інтерфейс сховища та створюють для вас класи. Ви ніколи не побачите цих класів, і ви не зможете створювати нові екземпляри, але вам цього не потрібно, оскільки ви можете просто автонаправити інтерфейс і дозволити Spring знайти цей об’єкт сховища.
Шаблон DAO та сховища - це способи реалізації рівня доступу до даних (DAL). Отже, почнемо спочатку з DAL.
Об'єктно-орієнтовані програми, які отримують доступ до бази даних, повинні мати певну логіку для обробки доступу до бази даних. Щоб зберегти код чистим та модульним, рекомендується, щоб логіка доступу до бази даних була виділена в окремий модуль. У багатошаровій архітектурі цей модуль є DAL.
Поки ми не говорили про якусь конкретну реалізацію: лише про загальний принцип, який включає логіку доступу до бази даних в окремий модуль.
Тепер, як ми можемо реалізувати цей принцип? Ну, один із відомих способів реалізації цього, зокрема з такими рамками, як Hibernate, - це модель DAO.
Шаблон DAO - це спосіб генерування DAL, де зазвичай кожна доменна сутність має свій власний DAO. Наприклад, User
і UserDao
, Appointment
і AppointmentDao
, і т. Д. Приклад DAO з Hibernate: http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .
Тоді що таке шаблон сховища? Як і DAO, шаблон сховища - це також спосіб досягнення DAL. Основний момент шаблону репозиторію полягає в тому, що, з точки зору клієнта / користувача, він повинен виглядати або вести себе як колекція. Що мається на увазі під поведінкою, як колекція, це не те, що вона має бути подібною до неї Collection collection = new SomeCollection()
. Натомість це означає, що він повинен підтримувати такі операції, як додавання, видалення, вміст тощо. Це суть шаблону репозиторію.
На практиці, наприклад, у випадку використання сплячого режиму, шаблон репозиторію реалізується за допомогою DAO. Це екземпляр DAL може бути одночасно і тим самим екземпляром шаблону DAO, і шаблоном сховища.
Шаблон сховища - це не обов'язково щось, що створюється на базі DAO (як деякі можуть запропонувати). Якщо DAO розроблені з інтерфейсом, який підтримує вищезазначені операції, то це екземпляр шаблону репозиторію. Подумайте над тим, якщо DAO вже надають збірний набір операцій, то яка потреба в додатковому шарі поверх нього?
Чесно кажучи, це виглядає як семантичне розрізнення, а не технічне розмежування. Фраза "Об'єкт доступу до даних" взагалі не посилається на "базу даних". І хоча ви могли б спроектувати його як орієнтованого на базу даних, я думаю, що більшість людей вважають за все це недолік дизайну.
Мета DAO - приховати деталі реалізації механізму доступу до даних. Чим відрізняється модель сховища? Наскільки я можу сказати, це не так. Скажіть, що сховище відрізняється від DAO, тому що ви маєте справу з поверненням колекції об'єктів і не може бути правильним; DAO також можуть повернути колекції об'єктів.
Все, що я читав про шаблон сховища, схоже, покладається на це розрізнення: поганий дизайн DAO проти хороший дизайн DAO (він же модель дизайну сховища).
Репозиторій - більш абстрактний доменно-орієнтований термін, який є частиною дизайну, керованого доменом, він є частиною дизайну вашого домену та загальною мовою, DAO - це технічна абстракція для технології доступу до даних, сховище стосується лише управління існуючими даними та фабриками для створення дані.
перевірте ці посилання:
http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html
Ключова відмінність полягає в тому, що репозиторій обробляє доступ до сукупних коренів у сукупності, тоді як DAO обробляє доступ до сутностей. Отже, прийнято, що сховище делегує фактичну стійкість корінних коренів DAO. Крім того, оскільки сукупний корінь повинен працювати з доступом інших об'єктів, то, можливо, буде потрібно делегувати цей доступ до інших DAO.
DAO забезпечує абстрагування файлів баз даних / даних чи будь-якого іншого механізму збереження, щоб шаром стійкості можна було маніпулювати, не знаючи деталей його реалізації.
В той час, як у класах репозиторію, кілька класів DAO можуть використовуватися всередині одного методу репозиторію, щоб отримати операцію з "точки зору програми". Отже, замість того, щоб використовувати кілька DAO на рівні домену, використовуйте сховище, щоб зробити це. Репозиторій - це шар, який може містити таку логіку програми, як: Якщо дані доступні в кеш-пам'яті, тоді вийміть її з кешу в іншому випадку, вийміть дані з мережі та зберігайте їх у кеш-пам'яті для наступного пошуку.
Репозиторій - це не що інше, як добре розроблений DAO.
ОРМ є орієнтованими на таблицю, але не DAO.
Немає необхідності використовувати декілька DAO у сховищі, оскільки DAO сам може зробити те саме з сховищами / організаціями ORM або будь-яким постачальником DAL, незалежно від того, де і як зберігається машина: 1 стіл, 2 таблиці, n таблиць, половина столу, a веб-сервіс, таблиця та веб-сервіс тощо. Послуги використовують декілька DAO / сховищ.
Мій власний DAO, скажімо, CarDao має справу лише з автомобілем DTO, я маю на увазі, тільки приймаю DTO Car на вході і повертаю лише колекції DTO автомобіля або DTO автомобіля у вихід.
Таким чином, як і сховище, DAO насправді є IoC, для бізнес-логіки, що дозволяє інтерфейсам стійкості не залякувати стратегіями переслідування або спадщиною. DAO і інкапсулює стратегію стійкості, і надає інтерфейс, пов'язаний з доменом. Сховище - це ще одне слово для тих, хто не розумів, що таке чітко визначений DAO.
Спробуйте дізнатися, чи DAO чи шаблон репозиторію найбільш застосовний до наступної ситуації: Уявіть, що ви хочете надати єдиний API доступу до даних для стійкого механізму для різних типів джерел даних, таких як RDBMS, LDAP, OODB, сховища XML та плоскі файли.
Також, якщо ви зацікавлені, зверніться до наступних посилань:
http://www.codeinsanity.com/2008/08/repository-pattern.html
http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/
http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx
дуже простим реченням: Суттєва різниця полягає в тому, що сховища представляють колекції, в той час як DAO розташовані ближче до бази даних, часто є набагато більш орієнтованими на таблицю.
У весняних рамках є анотація, яка називається сховищем, а в описі цієї анотації є корисна інформація про сховище, яка, на мою думку, є корисною для цього обговорення.
Вказує, що анотований клас - це "репозиторій", спочатку визначений дизайном, керованим доменом (Evans, 2003), як "механізм інкапсуляції зберігання, пошуку та пошукової поведінки, що імітує колекцію об'єктів".
Команди, що реалізують традиційні шаблони Java EE, такі як "Об'єкт доступу до даних", також можуть застосовувати цей стереотип до класів DAO, хоча перед цим слід постаратися зрозуміти відмінність між об'єктом доступу до даних та сховищами стилю DDD. Ця анотація є стереотипом загального призначення, і окремі команди можуть звужувати свою семантику та використовувати за необхідності.
Клас, зазначений таким чином, анотований, є придатним для весняного перекладу DataAccessException при використанні спільно з PersistenceExceptionTranslationPostProcessor. Також пояснюється анотований клас щодо його ролі в загальній архітектурі додатків з метою інструментальних засобів, аспектів тощо.
IRepository
інтерфейс. Ви хочете, щоб ваш сховище використовував DAO у своїй реалізації. Пам'ятайте, що DAO буде об'єктом за столом, тоді як для сховища майже завжди доведеться використовувати кілька DAO для створення однієї сутності. Якщо ви виявите, що це не так, що вашому сховищу та об'єкту потрібно лише отримати доступ до однієї таблиці, ви, швидше за все, будуєте анемічний домен.