Подтвердить что ты не робот

Имеет ли смысл использовать шаблон репозитория с базой данных документа?

В настоящее время я экспериментирую с MongoDB. Я перехожу из мышления NHibernate/SQL, поэтому изначально я реализовал шаблон репозитория для доступа к данным.

Все это выглядело отлично, пока я не начал использовать вложенные документы. Теперь это начинает казаться немного несоответствующим. Тем не менее, мне удобны репозитории и, как абстракция, разделение проблем и тестируемость, которые они предоставляют.

Успешно ли используют шаблон репозитория с базами данных документов? Если нет, какую методологию доступа к данным вы используете? Что относительно абстракции/SoC?

4b9b3361

Ответ 1

Это интересный вопрос. В моем использовании MongoDB я решил не иметь репозиторий. Это было первично, потому что база данных документов использовалась как хранилище для чтения (поэтому упрощало данные, которые там были сохранены).

Думаю, вам нужно отвлечь внимание на том, что такое репозиторий и какие преимущества вы получаете от дополнительного слоя абстракции. Хороший дизайн будет иметь наименьшее количество слоев.

Таким образом, репозиторий дает вам некоторое незнание персистентности и возможность использовать единицу работы над общим контекстом данных. Это также может увеличить вашу способность тестировать запросы по отдельным данным (поскольку они обычно абстрагируются как запросы или спецификации).

Кроме того, некоторые базы данных документов уже предоставляют шаблон репозитория (RavenDB и т.д.), поэтому нет необходимости иметь еще один слой.

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

Ответ 2

Я не знаю, поможет ли это вам, но я слушал pod-cast некоторое время назад, когда Айенде Рахиен говорил о RavenDB, Он предполагал, что документ действительно достаточно хорошо отображает совокупность в философии DDD. Если вы используете вложенные документы для представления совокупности и запускаете проблемы с дизайном, возможно, вложенность - это не лучший способ пойти?

Ответ 3

Я использую MongoDB в производственном коде с шаблоном хранилища более 2 лет, и могу сказать, что это действительно помогло мне со временем. Абстракции хорошо подходят для тестирования (в памяти) и производства (MongoDB).

Я использую Java, и код выглядит примерно так:

public interface MyStorage {

    boolean add(MyDoc doc);

    boolean update(MyDoc doc);

    boolean remove(String docId);

    boolean commit();

    MyDoc get(String docId);

    MyStorageQuery newQuery();

    List<MyDoc> query(MyStorageQuery q);

}

У меня есть factory для каждой реализации хранилища, которая создает новые экземпляры объекта MyDoc. Я меняю реализацию между MongoDb и моим собственным ручным макетом для тестирования.

В реализации MongoDB используется класс MyDoc, который расширяет объект BasicDBOb так:

public interface MyDoc {
  Data getData(); // let assume this is a nested doc
  void setData(Data d);
  String getId();
  long getTimestamp();
  void setTimestamp(long time);
}

MongoDbMyDoc extends BasicDBObject implements MyDoc {
  MongoDbObject() { }
  void setId(String id) {
    this.put("_id", id);
  }
  String getId() {
    return super.get("_id");
  }
  void setData(Data d) {
    dataObj = new BasicDBObject();
    dataObj.put("someField",d.someField);
    dataObj.put("someField2", d.someField2);
    super.put("data",dataObj);
  }
  ...
}

Затем в реальной реализации хранилища клиент MongoDB Java возвращает экземпляры моей реализации из БД. Вот конструктор для моей реализации хранилища MongoDB:

public MongoDbMyStorage(DB db, String collection) {
  //DB in a mongodb object (from the client library) which was instantiated elsewhere
  dbCollection = db.getCollection(collection);
  dbCollection.setObjectClass(MongoDbMyDoc.class);
  this.factory = new MongoDbMyDocFactory();
}

Здесь есть еще два интерфейса: MyStorageQuery, который также реализован как объект BasicDBOb для реализации MongoDB и создан с использованием newQuery() интерфейса хранения. И MyDocFactory, который здесь не представлен, но в основном документ factory, который знает, что такое реализация хранилища, и соответственно генерирует экземпляры MyDoc.

Предостережения:
Одна вещь, где абстракция не имеет особого смысла, заключается в определении индексов, используемых хранилищем MongoDB. Я поместил все мои вызовы ensureIndex(...) в конструкторе, но не очень общий, но определение индексов для каждой коллекции - это специфическая оптимизация MongoDB, поэтому я могу жить с ней.
Другим является то, что фиксация выполняется с помощью команды getLastError(), которая по моему опыту не работает так хорошо. Для меня это не проблема, так как я почти никогда не совершаю никаких изменений.

Ответ 4

Мысль о том, "должен ли я использовать X или нет", не так продуктивна, как сосредоточиться на "Что я должен использовать"?

Каковы альтернативы шаблону репозитория, каковы компромиссы и как они относятся к вашему домену и реализации?

Хранилища хороши для обеспечения предопределенного набора шаблонов в универсальном хранилище (например, SQL). Для хранилища документов мое впечатление заключается в том, что схема документа будет определять шаблоны доступа в большей степени, чем вы обычно видите в хранилище на основе SQL. Реализация хранилища в этом случае может привести к очень негерметичным абстракциям, когда изменения в базовой структуре документа оказывают влияние на соответствующий бизнес-код 1:1. В этом случае репозиторий обеспечивает очень мало значения. Для меня хранилища документов, естественно, хорошо подходят для парадигм Unit-of-Work (UoW), где единицей работы является документ (или doc + вложенные поддоны или наборы документов).

Другая сила шаблона репозитория - это, как вы сказали, абстракция над механизмом хранения. Компромисс, как правило, является потерей доступа к особенностям специфики Mongo на уровне низкого уровня. Это полезный компромисс для вас? NHibernate очень тесно связан с SQL и, следовательно, имеет богатые функциональные абстракции по всем важным функциям РСУБД. Я не знаю ни одной подобной структуры для Mongo, поэтому вы действительно будете поднимать уровень абстракции совсем немного.

Вам нужно поддерживать несколько параллельных хранилищ данных? Например, вы будете писать некоторые типы данных в SQL и другие для Mongo, используя ту же абстракцию уровня данных? Если это так, то репозиторий является хорошим вариантом.

Если вы можете предоставить более подробную информацию о своем домене и реализации, то мы можем еще немного углубиться в конкретные компромиссы, которые вы можете рассмотреть

Ответ 5

Эрик Эвенс (Eric Evens) в своей книге по управлению доменными именами имеет очень сложное и очень хорошее объяснение шаблона репозитория. Его определение - это то, каким должен быть хранилище и как его использовать (по моему личному мнению). Вы можете найти краткое описание здесь: Эрик Эванс в репозиториях

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