我担心我添加了太多接口

我正在构建我的域模型并继续重构它。 像我一样,我发现我喜欢接口,因为它允许我根据接口为具体类型创建可重用的方法/控制器/视图。 但是,我发现每次向其中一个域实体添加新属性时都会创建一个接口。

例如,我有一个MemberStatus对象,它inheritance自一个抽象的Entity对象,该对象又实现了IIdentifiableEntity接口,这意味着它具有Id属性。 MemberStatus还实现了INamedEntity接口,这意味着它具有Name属性, IOrderedEntity接口意味着它具有DisplayOrder属性, IHasMembers接口意味着它具有集合成员对象。 这是代码:

public class MemberStatus : Entity, INamedEntity, IOrderedEntity, IHasMembers { public string Name { get; set; } public float DisplayOrder { get; set; } public ICollection Members { get; set; } } public abstract class Entity : IIdentifiableEntity { public int Id { get; set; } } public interface IIdentifiableEntity { int Id { get; set; } } public interface INamedEntity { string Name { get; set; } } public interface IOrderedEntity { float DisplayOrder { get; set; } } public interface IHasMembers { ICollection Members { get; set; } } 

现在,这似乎工作正常,因为其他类似的对象,如MemberPositionMemberTeam都实现了这些相同的接口,我可以使用我的存储库方法和控制器操作与generics实现这些接口,并有大量的代码重用。

但是,我担心的是每次向具体对象添加新属性时是否继续添加简单的单属性接口是合适的。 例如,假设我想添加一个bool Enabled属性…我应该继续创建一个IEnabled接口吗? 我问的原因是一些使用generics的控制器“初始化器”变得非常长,如下面的代码行所示。 这是正常和最好的做法吗?

 public abstract class OrderedCrudController : CrudController where TEntity : Entity, INamedEntity, IOrderedEntity, IHasMembers, new() 

您使用接口的事实是一件好事。 但是,您应该问问自己,如果我创建一个IEnabled接口,我是否会仅通过该接口引用我的类? 即,是否存在我与我的class级互动纯粹通过界面暴露的单一属性的上下文?

另外,您是否可以考虑将与此IEnabled接口的多个实现交互的上下文?

如果这两个问题的答案都是“否”,则界面的用途很少。

话虽如此,请不要过于担心! 它的伤害很小。

不要创建您不希望迫切需要的接口。 观察YAGNI (你不需要它)的原则。 否则你会遇到不必要复杂的代码。

我认为你的问题在于你试图将你的领域模型用于你正在显示数据的任何gui。

相反,请考虑您的域对象具有接近数据的行为的事物及其c’tor,给它一个Action 。 现在,请确保您只能通过此操作从域对象传递数据OUT。

现在,你听。 每当您真的想要对您的域进行更改时,请在其上调用方法。 让您的GUI通过Action更新,方法是将这些事件保存到您感兴趣的任何读取模型中。

请查看http://www.infoq.com/presentations/ddd-eric-evans并考虑他关于域名事件的观点。

现在,您不必再将与技术域相关的奇怪接口添加到业务域中。 记住; 如果你像你的例子那样做CRUD,那么你不是在做域驱动设计。 你有一个贫血的领域。

最后一点:将接口用于实际需要互换的东西。 您是否在应用程序中携带了许多可以互换的INamed内容?

我还要链接这个,供您考虑: