Чем отличаются шаблоны сопоставления данных, шлюз табличных данных (шлюз), объект доступа к данным (DAO) и шаблоны репозитория?

133

Я пытаюсь освежить свои навыки проектирования шаблонов, и мне любопытно, каковы различия между этими шаблонами? Кажется, что все они одно и то же - инкапсулируют логику базы данных для конкретной сущности, чтобы вызывающий код не знал о базовом уровне персистентности. Из моего краткого исследования все они, как правило, реализуют ваши стандартные методы CRUD и абстрагируются от специфичных для базы данных деталей.

Помимо соглашений об именах (например, CustomerMapper против CustomerDAO против CustomerGateway против CustomerRepository), в чем разница, если таковые имеются? Если есть разница, когда бы вы выбрали один над другим?

В прошлом я писал код, подобный следующему (естественно, упрощенно - я бы обычно не использовал публичные свойства):

public class Customer
{
    public long ID;
    public string FirstName;
    public string LastName;
    public string CompanyName;
}

public interface ICustomerGateway
{
    IList<Customer> GetAll();
    Customer GetCustomerByID(long id);
    bool AddNewCustomer(Customer customer);
    bool UpdateCustomer(Customer customer);
    bool DeleteCustomer(long id);
}

и иметь CustomerGatewayкласс, который реализует конкретную логику базы данных для всех методов. Иногда я не использовал бы интерфейс и не делал все методы в CustomerGateway статическими (я знаю, я знаю, что это делает его менее тестируемым), поэтому я могу назвать его так:

Customer cust = CustomerGateway.GetCustomerByID(42);

Похоже, это тот же принцип для шаблонов Data Mapper и Repository; шаблон DAO (который, как мне кажется, аналогичен шлюзу?) также стимулирует использование шлюзов для конкретных баз данных.

Я что-то упускаю? Кажется немного странным иметь 3-4 разных способа сделать одну и ту же вещь.

Уэйн Молина
источник

Ответы:

97

Ваш пример условия; DataMapper, DAO, DataTableGateway и Repository, все имеют схожую цель (когда я использую одну, я ожидаю получить объект Customer), но разные намерения / смысл и итоговая реализация.

Repository «действует как коллекция, за исключением возможности более сложной запрашивающего» [ Evans, Domain Driven Design ] и может рассматриваться в качестве «объектов в фасаде памяти» ( Repository обсуждение )

DataMapper «перемещает данные между объектами и базой данных, сохраняя при этом их независимыми друг от друга и самого картографа» ( Fowler, PoEAA, Mapper )

TableDataGateway является «шлюзовой (объект , который инкапсулирует доступ к внешней системе или ресурса) в таблице базы данных. Один экземпляр обрабатывает все строки в таблице » ( Фаулера, PoEAA, TableDataGateway )

ДАО «отделяет клиентский интерфейс ресурса , обработок данных от его механизмов доступа к данным / адаптирует API доступа конкретного ресурса обработки данных для общего интерфейса клиента» , позволяющий «механизмы доступа к данным для изменения независимо от кода , который использует данные» ( ВС светокопии )

Репозиторий кажется очень общим, не раскрывая понятия взаимодействия с базой данных. DAO предоставляет интерфейс, позволяющий использовать различные базовые реализации базы данных. TableDataGateway - это, в частности, тонкая оболочка вокруг одного стола. DataMapper действует как посредник, позволяющий объекту модели развиваться независимо от представления базы данных (с течением времени).

Пирс Хикки
источник
15
По правде говоря, между DAO и TableDataGateway нет большой разницы, и в [Fowler, PoEAA] [1] они точно говорят: «[Alur et al.] [2] обсуждает шаблон объекта доступа к данным, который является шлюзом табличных данных. Я использовал другое имя, отчасти потому, что я рассматриваю этот шаблон как частное использование более общей концепции Gateway (466), и я хочу, чтобы имя шаблона отражало это ». [1]: martinfowler.com/books/eaa.html [2]: books.google.pt/books/about/…
Мигель Гамбоа
9
Хорошая точка зрения. У меня сложилось впечатление, что определение TableDataGateway, предоставленное PoEAA, уже, чем DataAccessObject. Первый, по-видимому, подразумевает взаимно-однозначное сопоставление с таблицей (реляционной) базы данных, где DAO может выступать в качестве фасада для нескольких базовых нереляционных ресурсов. В DAO акцент делается на замену базового хранилища данных, в TableDataGateway - на инкапсуляцию операций SQL над одной таблицей (необязательно в нейтральной / переносимой форме для хранилища данных).
Пирс Хики
31

В мире разработки программного обеспечения существует тенденция (по крайней мере, мне так кажется) изобретать новые имена для известных старых вещей и шаблонов. И когда у нас есть новая парадигма (которая, возможно, немного отличается от уже существующих вещей), она обычно поставляется с целым набором новых имен для каждого уровня. Таким образом, «бизнес-логика» становится «сервисным уровнем» только потому, что мы говорим, что делаем SOA, а DAO становится репозиторием только потому, что мы говорим, что делаем DDD (и каждый из них на самом деле вовсе не является чем-то новым и уникальным, но опять же: новые имена за уже известные понятия собранные в этой же книге). Поэтому я не говорю, что все эти современные парадигмы и аббревиатуры означают ТОЛЬКО одно и то же, но вы действительно не должны быть слишком параноиком по этому поводу. В основном это одни и те же модели, только из разных семей.

Дмитрий Перец
источник
4
@MladenMihajlovic, просто потому, что вы не понимаете или не согласны, не означает, что этот ответ недействителен или событие корректно.
Cypher
2
@MladenMihajlovic это не то, что говорит этот ответ. Последнее предложение подводит итог.
Cypher
2
@Cypher Эти шаблоны в основном одинаковы? Нет, они не. Реализация шаблона шлюза отличается от реализации шаблона репозитория. Они могут выглядеть одинаково для неподготовленного глаза, но это не так. Также, как правильно указал Младен Михайлович, этот ответ совершенно неверный. Бизнес-логика и сервисный уровень - это две разные вещи.
Фредерик Краутвальд
1
@Cypher На самом деле это не вопрос мнения, а факты. Паттерн Gateway был сформулирован Мартином Фаулером в его PoEAA и в основном связан с паттернами Фасад или Адаптер [GoF]. Различия заключаются в том, что шлюз написан для определенного использования и обычно не существует интерфейса. Шлюз, как правило, включает в себя только два объекта, а оборачиваемый ресурс не знает о шлюзе. (продолжение ...)
Фредерик Краутвальд,
3
Это больше комментарий, чем ответ.
Петур Инги Эгильссон
31

Data Mapper vs Table Data Gateway Короче говоря:

  • Data Mapper получит объект Domain Model (Entity) в качестве параметра и будет использовать его для реализации операций CRUD
  • шлюз табличных данных получит все параметры (в виде примитивов) для методов и ничего не будет знать об объекте модели домена (объекте).

    В конце они оба будут действовать как посредники между объектами в памяти и базой данных.

  • НАСКАР
    источник
    6
    ссылка устарела
    imel96
    1
    Обновленная ссылка: github.com/willdurand-edu/php-slides/blob/master/src/common/…
    Фернандо Коррейя
    15

    У тебя есть хорошая точка зрения. Выберите тот, который вам наиболее знаком. Я хотел бы отметить несколько вещей, которые могут помочь прояснить.

    Шлюз табличных данных используется в основном для одной таблицы или представления. Он содержит все операции выбора, вставки, обновления и удаления. Таким образом, Клиент - это таблица или представление в вашем случае. Итак, один экземпляр объекта шлюза табличных данных обрабатывает все строки в таблице. Обычно это связано с одним объектом на таблицу базы данных.

    В то время как Data Mapper более независим от любой предметной логики и менее связан (хотя я считаю, что есть связь или нет связи). Это просто промежуточный уровень для передачи данных между объектами и базой данных, сохраняя их независимость друг от друга и от самого преобразователя.

    Итак, обычно в маппере вы видите такие методы, как вставка, обновление, удаление, а в шлюзе табличных данных вы найдете getcustomerbyId, getcustomerbyName и т. Д.

    Объект передачи данных отличается от двух вышеупомянутых шаблонов, главным образом потому, что это шаблон распределения, а не шаблон источника данных, как вышеупомянутые два шаблона. Используйте его главным образом, когда вы работаете с удаленным интерфейсом и вам нужно сделать свои звонки менее разговорчивыми, поскольку каждый звонок может быть дорогим. Поэтому обычно проектируют DTO, который можно сериализовать по проводам, который может передавать все данные обратно на сервер для применения дальнейших бизнес-правил или обработки.

    Я не очень хорошо разбираюсь в шаблоне репозитория, так как до сих пор у меня не было возможности использовать его, но я буду смотреть на ответы других.

    Срикар Додди
    источник
    1

    Ниже только мое понимание.

    TableGateWay / RowDataGateWay : В этом контексте шлюз ссылается на конкретную реализацию, в которой каждый «объект домена» сопоставляется с каждым «шлюзом объекта домена». Например, если у нас есть Person , у нас будет PersonGateway для хранения объекта домена Person в базе данных. Если у нас есть Person, Employee, Customer и т. Д., У нас будут PersonGateway, EmployeeGateway и CustomerGateway. Каждый шлюз будет иметь определенную функцию CRUD для этого объекта, и он не имеет ничего общего с другим шлюзом. Здесь нет повторно используемого кода / модуля. Шлюз может быть далее разделен на RowDataGateway или TableGateway, в зависимости от того, передаете ли вы «id» или «object». Шлюз обычно сравнивают с активной записью. Он связывает вашу модель домена со схемой базы данных.

    Репозиторий / DataMapper / DAO : это одно и то же. Все они ссылаются на уровень сохраняемости, который переносит объекты базы данных в модель предметной области. В отличие от шлюза, репозиторий / DataMapper / DAO скрывают реализацию. Вы не знаете, есть ли PersonGateway позади Person. Это может или не может, вам все равно. Все, что вы знаете, это то, что для каждого объекта домена должны поддерживаться операции CRUD. Он разделяет источник данных и модель предметной области.

    Хао Лу
    источник