我个人没有让我的实体实现接口。对于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; }
}
答案 0 :(得分:2)
我曾经走过这条路(价值对象的接口)。这是背后的皇家痛苦,我建议反对它。它的常见论点是:
<强>惩戒:强> 它们是价值对象。没有嘲笑。另外,模拟最终会比编写构建器(使用Java)或使用C#中的命名参数更加痛苦。
只读视图 我必须承认,我仍然宁愿在默认情况下创建一些不可变的东西,只有在绝对需要时才使它变得可变。
隐藏功能 一般来说,范围已经涵盖了这个。
答案 1 :(得分:1)
这样做的主要好处是,它是一种将您的实体暴露为“只读”版本的方式(只要您的界面当然不会公开设置者)。
答案 2 :(得分:1)
我们正在进行相当多的单元测试,所以经常想要模拟我们没有测试的东西。虽然我不喜欢它,但我们最终都使用了遍布各处的接口,因为这样可以更容易地模拟事物。
理论上,大多数模拟框架也可以模拟普通类,但实际上这会引起我们的问题,因为我们有时用反射做聪明的事情,而模拟类的类型与原始类不同。这样做:
var myTask = MyIoCProvider.Get<Task>();
var taskType = typeof(myTask);
无法预测。鉴于:
var myTask = MyIoCProvider.Get<ITask>();
var taskType = typeof(myTask);
将您作为绝对来自ITask的任务类型。
因此接口只是让我们有一种方法可以使我们的系统更具可模仿性。
答案 3 :(得分:0)
如果你在考虑使用DomainEvents而不是数据结构,比如任务确实需要实现一个接口
public interface IDomainEvent
{
Guid EventId { get; }
Guid TriggeredByEvent { get; }
DateTime Created { get; }
}
public class OrderCancelledEvent : IDomainEvent
{
Guid EventId { get; set; }
Guid TriggeredByEvent { get; set; }
DateTime Created { get; set; }
// And now for the specific bit
int OrderId { get; set; }
}
或者类似地,如果你有一个公共数据访问层,可能需要接受IEntity的标准基类,但如果它只是你在帖子中描述的数据结构,我就没有每种类型的接口。
当您处理实际暴露行为的域对象时,您可能希望拥有一个用于单元测试的接口。
答案 4 :(得分:0)
我认为有些程序员只是使用接口,因为他们听说接口很好,所以他们没有考虑实际的利弊而结束在任何地方使用它们。
就我个人而言,我从不使用接口来处理仅表示一条数据的实体,例如 db row。