首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >储存库模式的变化

储存库模式的变化
EN

Code Review用户
提问于 2011-07-01 15:29:08
回答 3查看 1.7K关注 0票数 2

我已经用了一年多的存储库模式的这种变体:

代码语言:javascript
运行
复制
 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);
}

但是最近,在重新阅读了一些关于设计模式的书之后,我有了一个似乎很棒的想法,将一些模式应用到我的存储库中。

代码语言:javascript
运行
复制
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
    }
}

这样就会被称为:

代码语言:javascript
运行
复制
_myRepository.Execute(new SaveCommand());

我的推理是,为公共数据访问操作(例如保存、删除)放置逻辑非常重复,以至于现在每当我有一个新实体进入竞技场时,我都依赖T4模板重新创建这些操作。通过这种方式,我只需要定义最常用的数据访问操作,然后让我的调用方execute执行他们需要执行的任何操作。

你能批评我的作品吗?我确实有过度思考和过度设计事物的倾向。

EN

回答 3

Code Review用户

回答已采纳

发布于 2011-07-03 06:26:51

尽管您引入的命令模式使得创建一个“灵活”的执行方法变得很容易。我想知道对于那些读过你的代码的人来说,这是否真的是透明的。

也许您可以通过使用命令对象实现特定的ReadOnlyRepository来组合您的两个想法。这样,您的interace的用户就可以继续使用:

代码语言:javascript
运行
复制
repository->Update(SomeEntity);

而存储库实现可以:

代码语言:javascript
运行
复制
repository.Execute(new UpdateCommand());

考虑一下,如果您必须对以后的接口进行更改。您需要在哪里更新代码中的内容?在我的建议中,它只是要求你在一个地方改变它。(因为所有其他代码仍然使用“旧”接口)。

我希望我的帖子有意义:)

票数 1
EN

Code Review用户

发布于 2011-07-01 20:51:49

我认为引入明确的工作单元是有用的,这些工作单元可以在需要的领域使用,比如Save()。我还建议使用一个通用Query()接口,它需要lambda来提高检索的灵活性。您还可以考虑异步方案。

票数 0
EN

Code Review用户

发布于 2011-07-04 02:30:44

我的大部分保存和删除etc都是在一个基本存储库类中处理的,所以我不会真正地重复任何事情。

所以对于很多你只需要的东西..。

IBlahRepository继承IRepository

ConcreteBlahRepository继承IBlahRepository和Repository

在实体上都是泛型的。

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/3247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档