【问题标题】:Too Much Abstraction/Interfaces太多抽象/接口
【发布时间】:2011-07-26 11:01:41
【问题描述】:

我正在设计我的数据访问代码,数据将存储在 RavenDB 中,我正在尝试查看我当前的设计是否对我将拥有的接口数量过多的抽象。

我将拥有仅保存数据的 DTO,然后我将拥有将具有额外功能的实体(或模型、业务或任何您称之为的)对象。我还将为每个实体提供一个接口,定义它需要拥有的数据。比如:

interface IUser
{
    string Id { get; }
    string Username { get; }
    string Password { get; }
    bool ResetPassword { get; }
}

class UserDTO : IUser
{
    public string Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }

    public UserDTO()
    {
        Id = null;
        Username = null;
        Password = null;
        ResetPassword = false;
    }
}

class User : IUser
{
    public string Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }

    public User()
    {
        Id = null;
        Username = null;
        Password = null;
        ResetPassword = false;
    }

    public User(IUser user)
    {
        Id = user.Id;
        Username = user.Username;
        Password = user.Password;
        ResetPassword = user.ResetPassword;
    }

    public ResetPassword()
    {
        Id = null;
        Username = null;
        Password = null;
    }
}

我希望每个实体都有一个接口的原因是因为我想确保EntityDTOEntity 都具有所需的共享数据。

现在为了检索和保存数据,我将使用存储库模式。我将拥有一个名为IDataRepository 的通用接口,然后每个实体都将拥有自己的存储库接口。例如:

interface IDataRepository<T>
{
    bool Save(T entity);
    bool Delete(T entity);
}

interface IUserRepository : IDataRepository<IUser>
{
    IUser Load(string key);
    IUser LoadByLogin(string username, string password);
}

class UserRepository : IUserRepository
{
    bool Save(T entity)
    {
        //save code
    }

    bool Delete(T entity)
    {
        //delete code
    }

    IUser Load(string key)
    {
        //load code
    }

    IUser LoadByLogin(string username, string password)
    {
        //load code
    }
}

我希望每个实体都有一个存储库接口的原因是,如果我需要为不同的实体使用不同的数据存储选项,我可以这样做。

这看起来是不是太抽象了?

【问题讨论】:

  • 为什么要区分UserUserDTO
  • 这看起来像抽象吗?你的意思是?你能澄清一下你想要达到的目标吗?
  • 因此您从存储库加载 IUser。你接下来会做什么?将其投射给用户?同样从提供的信息来看,没有证据表明确实需要 DTO。
  • 对不起,我上一个问题中缺少的单词,更新

标签: c# design-patterns data-access-layer


【解决方案1】:

我认为这种模式有其优点和缺点。如果您的 DTO 要与实体匹配,为什么要有 DTO?在某些系统中,这是需要发生的事情,而在其他系统中,这是浪费时间。实体通常有包袱,并且根据 ORM 不能很好地序列化。如果您使用该接口,则可以使用 AutoMapper 完成 DTO 和实体之间的映射,并且每次都可以正常工作。您是否需要将实体类与 DTO 放在一个单独的 DLL 中?如果是这样,我认为您的模型有效。

【讨论】:

    【解决方案2】:

    从本质上讲,我觉得你所拥有的一切都很好。

    但是,除非您进一步区分 DTO 和 Entity 类并且明确需要将两者分开,否则我将简单地将 User 扩展 UserDTO 并一起删除接口。这样,您就可以消除当前拥有的代码冗余。

    【讨论】:

      【解决方案3】:

      是的,这太抽象了。具体来说,我认为不需要 UserDTO 对象类。

      IUser 本身应该定义数据存储库完成其工作所需的完整接口。如果存储库收到一个实现IUser 的对象,例如User,那么它应该能够很好地存储数据。而且,由于接口是在最低级别定义的,因此省略 UserDTO 对象不会产生任何依赖问题。

      【讨论】:

      • 我认为我们对系统的了解不够多,不能说太多。如果这是一个在公司内为项目分发的 DLL,您是否仍想传回可能带有您不想授予访问权限的挂钩的实体?
      • @CrazyDart - 如果 OP 担心实现存储库层的人将在其 IUser 实例上使用反射来获得对受限功能的访问权限,那么这确实应该说明在问题中!
      猜你喜欢
      • 2014-08-23
      • 2011-05-22
      • 2011-02-09
      • 1970-01-01
      • 2017-02-19
      • 2014-04-12
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多