实体应该实现接口吗?

时间:2010-11-17 11:58:50

标签: c# class-design

我个人没有让我的实体实现接口。对于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; }
}

5 个答案:

答案 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。