代码之家  ›  专栏  ›  技术社区  ›  Neil Barnwell

实体应该实现接口吗?

  •  6
  • Neil Barnwell  · 技术社区  · 15 年前

    我个人没有让我的实体实现接口。对于一个 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; }
    }
    
    4 回复  |  直到 15 年前
        1
  •  2
  •   Michael Lloyd Lee mlk    15 年前

    我曾经走过这条路(价值对象的接口)。这是一种皇家的背部疼痛,我建议不要这样做。它的常见参数是:

    嘲笑: 它们是价值对象。没什么好嘲笑的。加嘲讽的结尾是一个很大的痛苦,而不是写一个建设者(在爪哇)或使用命名参数的东西在C。

    只读视图: 我必须承认,默认情况下,我仍然喜欢使某个东西不可变,只有在绝对需要时才使其可变。

    隐藏功能: 一般来说,范围已经为我涵盖了这一点。

        2
  •  1
  •   Klaus Byskov Pedersen    15 年前

    这样做的主要好处是,它是一种将实体公开为“只读”版本的方法(当然,只要您的接口不公开setters)。

        3
  •  1
  •   d4nt    15 年前

    我们正在做大量的单元测试,所以经常想模拟一些我们没有测试的东西。尽管我不喜欢它,但我们最终还是在各地使用了接口,因为这样可以更容易地模拟事物。

    理论上,大多数模拟框架也可以模拟普通类,但在实践中,这给我们带来了一些问题,因为我们有时会做一些巧妙的事情,并且模拟类的类型与原始类不同。这样做:

    var myTask = MyIoCProvider.Get<Task>();
    var taskType = typeof(myTask);
    

    是不可预测的。鉴于:

    var myTask = MyIoCProvider.Get<ITask>();
    var taskType = typeof(myTask);
    

    将您作为任务类型提供,该任务类型肯定是从ITask派生的。

    所以界面只是给了我们一种让我们的系统更具可模仿性的方法。

        4
  •  0
  •   Ian Johnson    15 年前

    如果您考虑使用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基类,但是如果它只是您在文章中描述的数据结构,那么对于每种类型,我都没有接口。

    当您处理实际公开行为的域对象时,您可能需要一个用于单元测试的接口。