实体应该实现接口吗?
我个人没有让我的实体实现接口。对于 Task
类,我不会让 ITask
只定义了相同的属性。
不过,我已经见过几次这样的做法,所以我想知道这些建议从何而来,以及您从中获得什么好处。
如果您使用的是 ORM,那么“我可以更改我的数据访问”的论点是无关紧要的,那么这样做还有什么其他原因呢?
更新:
关于 INotifyPropertyChanged
的评论提出了一个很好的观点。但这不是我的重点 - 我说的是这样的事情:
public interface ITask
{
int Id { get; set; }
string Description { get; set; }
}
public class Task : ITask
{
public int Id { get; set; }
public string Description { get; set; }
}
I personally don't have my entities implement interfaces. For a Task
class I wouldn't have ITask
that just had the same properties defined on it.
I've seen it done a few times though, so I'm wondering where that advice comes from, and what benefits you get from it.
If you're using an ORM then the argument that says "I can change my data access" is irrelevent, so what other reason is there for doing this?
UPDATE:
A good point was made in the comments about INotifyPropertyChanged
. That wasn't my point though - I'm talking about having something like this:
public interface ITask
{
int Id { get; set; }
string Description { get; set; }
}
public class Task : ITask
{
public int Id { get; set; }
public string Description { get; set; }
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我曾经走过这条路(值对象的接口)。这是一种巨大的后背疼痛,我建议不要这样做。它的常见论点是:
模拟:
它们是价值对象。没什么好嘲笑的。另外,与编写构建器(用 Java)或使用 C# 中的命名参数相比,模拟最终会带来很大的痛苦。
只读视图:
我必须承认,我仍然更喜欢默认设置不可变的东西,只有在绝对需要时才使其可变。
隐藏功能:
一般来说,范围对我来说已经涵盖了这一点。
I went down this road once (interfaces for value objects). It was a royal pain in the backside, I recommended against it. The common arguments for it are:
Mocking:
They are value objects. Nought to mock. Plus mocking ends up being a large pain than either writing a builder (in Java) or using the named arguments stuff in C#.
Readonly views:
I must admit I still prefer to make something immutable by default, only making it mutable if absolutely required.
Hidden functionality:
Generally scope has covered this one for me.
这样做的主要好处是,它是一种将实体公开为“只读”版本的方法(当然,只要您的接口不公开设置器)。
The major benefit of this is that it is a way of exposing your entity as a "read-only" version (as long as your interface does not expose setters of course).
我们正在进行大量的单元测试,因此经常想要模拟我们没有测试的东西。尽管我不喜欢它,但我们最终还是在各处使用了接口,因为它使模拟事物变得更加容易。
理论上,大多数模拟框架也可以模拟普通类,但实际上这给我们带来了问题,因为我们有时会通过反射做一些聪明的事情,并且模拟类的类型与原始类不同。这样做
是不可预测的。而:
为您提供肯定是从 ITask 派生的任务类型。
因此,接口只是为我们提供了一种使我们的系统更加可模拟的方法。
We're doing quite a bit of unit testing and so often want to mock out things we're not testing. Although I don't like it, we've ended up using interfaces all over the place because it makes it a lot easier to mock things.
In theory most of the mocking frameworks can mock normal classes too, but in practice this has caused us issues because we sometimes do clever things with reflection and the type of the mocked class isn't the same as the original. So doing:
Was unpredictable. Whereas:
Gives you as taskType that IS definitely derived from ITask.
So interfaces just give us a way of making our system more mockable.
如果您正在考虑使用 DomainEvents 而不是数据结构(例如任务)确实需要实现一个接口
,或者类似地,如果您有一个公共数据访问层,可能需要采用 IEntity 的标准基类,但我不会如果每种类型只是您在帖子中描述的数据结构,则有一个接口。
当您处理实际公开行为的域对象时,您可能需要一个用于单元测试的接口。
If you were thinking in terms of using DomainEvents than data structures such as the task really do need to implement an interface
Or similarly if you have a common data access layer that may need to take in a standard base class of IEntity but I wouldn't have an interface for each type if it is just a data structure as you describe in your post.
When you are handling Domain Objects that actually expose behaviour you may then want to have an interface for unit testing.
我认为有些程序员只是使用接口,因为他们听说接口很好,所以他们最终在任何地方都使用它们,而不考虑实际的利弊。
就我个人而言,我从不使用仅代表一条数据(例如数据库行)的实体的接口。
I think some programmers just use interfaces, because they heard interfaces are good so they ended using them everywhere without thinking about actual pros and cons.
Me personally, I never use interfaces for entities that only represent a piece of data like db row for example.