我正在设计我的数据访问代码,数据将存储在RavenDB中,我试图看看我当前的设计是否有太多的抽象,我将拥有的接口数量。
我将拥有只保存数据的DTO,然后我将拥有具有额外功能的Entity(或Model,Business或任何你称之为的对象)对象。我还将为每个实体定义一个接口,定义它需要具有哪些数据。例如:
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;
}
}
我希望为每个实体提供接口的原因是因为我想确保EntityDTO
和Entity
都具有所需的共享数据。
现在,为了检索和保存数据,我将使用存储库模式。我将有一个名为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
}
}
我想为每个实体建立一个存储库接口的原因是,如果我需要为不同的实体使用不同的数据存储选项,我可以这样做。
这看起来像抽象太多了吗?
答案 0 :(得分:1)
我认为这种模式有其商品和坏处。如果您的DTO要与实体匹配,为什么要有DTO?在某些系统中,这是需要发生的事情而在其他系统中则是浪费时间。实体通常有行李,并且根据ORM不能很好地序列化。如果使用该接口,则可以使用AutoMapper完成DTO和实体之间的映射,并且每次都可以正常工作。您是否需要将实体类置于与DTO不同的DLL中?如果是这样,我认为你的模型有效。
答案 1 :(得分:1)
是的,这太抽象了。具体来说,我认为不需要UserDTO
类对象。
IUser
本身应该定义数据存储库完成其工作所需的完整接口。如果存储库被传递给实现IUser
的对象,例如User
,那么它应该能够很好地存储数据。并且,由于接口是在最低级别定义的,因此省略UserDTO
对象不会产生任何依赖性问题。
答案 2 :(得分:0)
你所拥有的,实质上对我来说似乎很好。
但是,除非您在DTO和实体类之间进一步区分,并且明确需要将两者分开,否则我只需要User
扩展UserDTO
并将所有接口一起删除。这样,您就可以删除当前的代码冗余。