我有一个界面" IUser"和一个班级"用户"实施" IUser"。我还有一个存储库接口" IUserRepository"。
我介于这两个选项之间:
public interface IUserRepository
{
List<User> getAll();
void addUser(User user);
void alterUser(User user);
void deleteUser(string ID);
bool validateLogin(string session_user, string session_pass);
User getUserByID(int ID);
User getUserByNombre(string name);
User getUserBySessionUser(string session_user);
}
和这个
public interface IUserRepository
{
List<IUser> getAll();
void addUser(IUser user);
void alterUser(IUser user);
void deleteUser(string ID);
bool validateLogin(string session_user, string session_pass);
IUser getUserByID(int ID);
IUser getUserByNombre(string name);
IUser getUserBySessionUser(string session_user);
}
这是我的困惑。我的存储库接口中的方法是否应该返回实际的实现或接口?正如你在我的第一个选项中看到的那样,我正在回归&#34;用户&#34;实例。我应该回过头来松散地结合代码?
但是如果我在用户存储库的实际实现中选择第二个,我将只能访问我在IUser接口中声明的方法和属性。
例如,如果我从服务中调用addUser方法传递User类的实例:
myRepositoryImplementation.addUser(UserInstance);
然后我真正的存储库将会像这样
private readonly IUser user;
public void addUser(IUser _user)
{
this.user=_user;
}
好有效的捕捉!但是我只能访问最初在IUser接口中声明的方法和属性,而不能访问我的User实例中声明的任何新方法或属性。
如果我调用getUserByID方法,我将收到一个IUser实例。
所以要恢复这个
1)。这些有效的方法吗?
2)。如果这些是有效的方法,我应该用它来保存或保持代码解耦?
3)。如果我选择第二个,如果它是有效的,那么我应该在界面中声明我将要使用的所有内容吗?我的意思是属性和方法?
3)。有更好的主意吗?
答案 0 :(得分:2)
我肯定会选择第一个选项。拥有像存储库这样的服务类的接口很有用,但是对于像User这样的实体类,并不是那么多。
正如您所说,每次添加属性时,您还需要将属性添加到接口,这很乏味。假设您的用户类是一个没有依赖于其他类的简单类,即使没有接口也很容易测试。
相关阅读:
http://lostechies.com/jamesgregory/2009/05/09/entity-interface-anti-pattern/
实体上的接口是一种反模式 - 詹姆斯格雷戈里博客
答案 1 :(得分:2)
1)是的,两者都有效
3)是,属性和方法
2)一个更长的故事。简而言之,如果您有POCO类并且您100%确定您永远不会针对不允许您使用POCO的框架进行编码(例如,它坚持继承从特定于框架的基类继承的类),你可以选择第一个选项(类)。
但它并不总是有效。
例如,为实体框架代码编写Linq2SQL和其他存储库的存储库编码,您不能使用完全相同的类集。第二种(接口)方法是唯一的选择。我们已成功地在多个企业应用程序中使用它而没有任何问题。
建议 - 如果你使用接口方法,你肯定需要一个方法来创建一个空实例
public interface IUserRepository
{
List<IUser> getAll();
...
IUser CreateNew();
}
否则,存储库客户端没有其他方法可以创建具体类型的实例 - 客户端不知道该类型。但是,有些人倾向于将创建方法移动到单独的工厂类中。
答案 2 :(得分:1)
我认为您的部分困惑在于您的User类中有方法。通常,这些类型的模型类仅表示数据,而不描述行为。所以,如果你把你的方法移到更适合的地方,你的整个混乱就会消失,因为没有理由建立一个界面。
换句话说,将方法移出User类并让您的repo工作如下:
List<User> getAll();