我通常为我的ASP.NET项目创建一个外部类库,我将它引用到我正在处理的项目上然后在任何一个webforms上我创建该类的对象并从代码中访问其属性和方法落后如此:
User usr = new User();
usr.Username = "Username";
usr.Password = "Password";
usr.Register();
我目前正与我的一位同事合作,他称之为“糟糕的设计”,尤其是当我为他生成类图时。据他说,他说这是“糟糕的设计/编程,直接在代码后面的文件中实例化对象一个网络形式。他说我应该使用接口,这样如果对类库进行了更改,我的应用程序就不会抱怨前端的任何错误,这意味着我不必更改前端的任何内容。例如。如果我将“公共字符串用户名”更改为“公共字符串用户”,它不应该在前端给我任何错误,关于代码独立性或类似的东西。所以:
Interface IU = new User();
IU.Username = "Username";
IU.Password = "Password";
IU.Register();
这是我自己的理解,但我希望有人来验证和澄清这一点。
答案 0 :(得分:2)
这始终是意见和最佳实践的问题。
就我个人而言,我没有看到为你的域对象创建接口的任何意义(明显的例外是它作为两个域对象之间的通用契约)。
界面在层之间非常有用。我不是创建一个代表IUser的接口,而是为Register方法声明一个接口。
这是设计发生变化的地方。您将注册方法声明为用户本身的一部分。这是一种称为Active Record的常见模式。我个人并不喜欢这种方法,原因如下:
我的建议是创建一个User类,然后使用Register()方法将其传递给业务逻辑类。然后,此业务逻辑类将实现IManagerUsers(或任何您希望调用它的方式)。
public class User
{
public string Username{get;set;}
public string Password{get;set;}
}
public interface IUserManager
{
bool Register(User user);
}
public class UserManager : IUserManager
{
public bool Register(User user)
{
// register your user here
}
}
答案 1 :(得分:0)
它与重命名无关,因为如果重命名接口方法,它仍然会破坏客户端。
对我来说,界面最好的事情就是你可以很容易地模仿它们。你不能用真正的班级做到这一点。
即。我们假设您想要对创建新用户的方法进行单元测试。例如CreateNewUser()
会创建一个新的User
对象,并在其上调用Register
。
使用接口,您可以模拟User
对象并强制其假Register
方法返回一个值,这对您的测试意味着什么。即:
//arrange
var u = new Mock<IUser>;
u.Setup(x => x.Register()).Returns(true);
//act
var newUser = CreateNewUser();
//assert
Assert.IsNotNull(newUser);
您可以针对Register
何时返回false进行另一次测试,依此类推。
不使用接口,您的单元测试会如何?
答案 2 :(得分:0)
软件开发的一个原则是保持不同的系统松散耦合。在当前上下文中使用接口可帮助您执行相同操作。例如,如果您将IUser作为接口,则可以在客户端代码中使用任何实现IUser接口的类。
public class RegisterClass{
private IUser _user;
public RegisterClass(IUser user){
_user = user;
};
public void Validate(){
//you can validate the IUser.
}
}
public class UserOne : IUser {
}
public class UserTwo : IUser {
}
现在可以灵活地使用任何具有IUser作为接口的具体类。