我已经用了一年多的存储库模式的这种变体:
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模板重新创建这些操作。通过这种方式,我只需要定义最常用的数据访问操作,然后让我的调用方execute执行他们需要执行的任何操作。
你能批评我的作品吗?我确实有过度思考和过度设计事物的倾向。
发布于 2011-07-03 06:26:51
尽管您引入的命令模式使得创建一个“灵活”的执行方法变得很容易。我想知道对于那些读过你的代码的人来说,这是否真的是透明的。
也许您可以通过使用命令对象实现特定的ReadOnlyRepository来组合您的两个想法。这样,您的interace的用户就可以继续使用:
repository->Update(SomeEntity);而存储库实现可以:
repository.Execute(new UpdateCommand());考虑一下,如果您必须对以后的接口进行更改。您需要在哪里更新代码中的内容?在我的建议中,它只是要求你在一个地方改变它。(因为所有其他代码仍然使用“旧”接口)。
我希望我的帖子有意义:)
发布于 2011-07-01 20:51:49
我认为引入明确的工作单元是有用的,这些工作单元可以在需要的领域使用,比如Save()。我还建议使用一个通用Query()接口,它需要lambda来提高检索的灵活性。您还可以考虑异步方案。
发布于 2011-07-04 02:30:44
我的大部分保存和删除etc都是在一个基本存储库类中处理的,所以我不会真正地重复任何事情。
所以对于很多你只需要的东西..。
IBlahRepository继承IRepository
ConcreteBlahRepository继承IBlahRepository和Repository
在实体上都是泛型的。
https://codereview.stackexchange.com/questions/3247
复制相似问题