Вариации шаблон репозитория


Я использую этот вариант шаблона repository за год:

 public interface IReadOnlyRepository<T, in TId>
     where T : AbstractEntity<TId>
    {
        T Get( TId id );
        IEnumerable<T> GetAll();
    }

/// <summary>
/// Defines a generic repository interface for
/// classes solely in charge of getting and processing data from a data source
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TId">The type of the id.</typeparam>
public interface IRepository<T, in TId> : IReadOnlyRepository<T, TId> where T : AbstractEntity<TId>
{
    /// <summary>
    /// Determines whether the specified entity has duplicates.
    /// </summary>
    /// <param name="entity">The entity.</param>
    /// <returns>
    ///   <c>true</c> if the specified entity has duplicates; otherwise, <c>false</c>.
    /// </returns>
    bool HasDuplicates(T entity);

    /// <summary>
    /// Inserts the specified entity.
    /// </summary>
    /// <param name="entity">The entity.</param>
    void Save( T entity );
    /// <summary>
    /// Inserts the entity or updates it if it already exists.
    /// </summary>
    /// <param name="entity">The entity.</param>
    T SaveOrUpdate( T entity );

    /// <summary>
    /// Updates the specified entity.
    /// </summary>
    /// <param name="entity">The entity.</param>
    /// <returns></returns>
    T Update(T entity);

    /// <summary>
    /// Deletes the specified entity from the data source.
    /// </summary>
    /// <param name="entity">The entity.</param>
    void Delete(T entity);

    /// <summary>
    /// Deletes the entity with the specified id.
    /// </summary>
    /// <param name="id">The id.</param>
    void Delete(TId id);
}

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

public interface IRepository<T, in TId> : IReadOnlyRepository<T, TId> where T : AbstractEntity<TId>
{
    void Execute(IRepositoryCommand command);
    void Execute(IBatchRepositoryCommand command);
}

public interface IRepositoryCommand<T>
{
    void Execute(T entity);
}

public interface IBatchRepositoryCommand<T>
{
    void Execute(IEnumerable<T> entities);
}

public SaveCommand<T> : IRepositoryCommand<T> 
{
    public void Execute(T entity)
    {
        // Logic for saving goes here
    }
}

public BatchSaveCommand<T> : IRepositoryCommand<T>
{
    public void Execute(IEnumerable<T> entities)
    {
        // Logic for batch saves go here
    }
}

которые затем будут называться так:

_myRepository.Execute(new SaveCommand());

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

Вы можете критиковать мою работу? У меня есть тенденция думать и overengineer вещи.



1691
2
задан 1 июля 2011 в 03:07 Источник Поделиться
Комментарии
3 ответа

Хотя команда шаблон, вы привели легко создать "гибкий" метод execute. Я интересно, если это действительно прозрачным, чтобы те, кто читает ваш код.

Возможно, вы сможете объединить ваши две идеи, реализуя определенные ReadOnlyRepository с помощью командных объектов. Так что пользователь interace продолжает использовать:

repository->Update(SomeEntity);

При реализации репозитория делает:

repository.Execute(new UpdateCommand());

Рассмотреть, если вы должны были внести изменения в свой позже интерфейса. Где бы вы изменить в коде? В мое предложение он просто требует от вас, чтобы изменить его в одном месте. (поскольку все другие код по-прежнему использует "старый" интерфейс).

Я надеюсь, что мой пост имеет смысл :)

1
ответ дан 3 июля 2011 в 06:07 Источник Поделиться

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

0
ответ дан 1 июля 2011 в 08:07 Источник Поделиться

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

так много вещей, которые вы только действительно нужно....

IBlahRepository наследует IRepository

ConcreteBlahRepository наследует IBlahRepository и репозитория

что все родовые сущности

0
ответ дан 4 июля 2011 в 02:07 Источник Поделиться