代码之家  ›  专栏  ›  技术社区  ›  Otávio Décio

接口应该知道域对象吗?

  •  8
  • Otávio Décio  · 技术社区  · 14 年前

    在我的系统中,我有两个不同的项目,一个定义它的接口,另一个定义它的域对象。到目前为止,我设法使接口定义独立于域对象,但我现在感觉需要包括某些域对象,要么作为接口中定义的方法的参数,要么作为这些方法的返回值。

    编辑-发布问题后,我想为每个域对象定义一个接口,这样它们就可以保持独立-不知道这是否是过度杀伤力,也不知道这是否是他们保持独立的代价。

    编辑#2-我被要求举一个例子,所以我会尽量保持简单。我有一个处理图像转换的进程,我的一个域对象是一个类,它包含诸如分辨率、页面列表、哈希等信息。让它称为DocumentInfo。我有一个类,它使用DocumentInfo来执行一些操作,比如generatePDFromTiff;我首先将GeneratePdfFromTiff定义为IImageHandler的接口方法,然后由ImageHandler实现。

    4 回复  |  直到 14 年前
        1
  •  3
  •   mnemosyn    14 年前

    这个很难,我来试试+问题是1。

    我认为,如果在现实世界中,领域模型应该知道如何与彼此的内部工作进行交互。当然,这在很大程度上取决于您的确切域模型,因为同一事物的不同模型会产生非常不同的表示。

    每个域模型类的接口的问题是,域模型本身已经是一个关于现实的特定视图,就像接口一样。接口仅在该特定域中有效。你不能用同样的 ICar 用于交通规划、家庭收入计算器和汽车空气动力学优化。

    因此,我怀疑将它们的依赖关系隔离得太远是否有用。

    据我所知,接口大多(总是?)是公共的,这会导致访问问题。接口不应公开有关实现的详细信息,但域模型类包含实际实现。因此,您必须为每个细节创建另一个抽象机制,而不是“仅仅访问某个值”。例如,您不能访问系统中的任何ID、用户等。你需要一个抽象的ID类型,一个ID提供者,等等。我相信在一个大的现实世界模型中这可能是非常麻烦的。

    当然,某些“自然领域边界”仍然应该是孤立的。如果您构建了一个社交文本编辑器,那么在传统文本编辑器中出现的所有域类都应该与社交网络相关的项完全隔离。因此,文本编辑器应该只知道 IUser . 但我想我不会告诉你任何新的。。。

        2
  •  2
  •   user180326 user180326    14 年前

    我会记住使用界面的软件工程师的兴趣。尝试去耦合会使代码更抽象,而且通常更难使用。这意味着需要编写更多的代码来“完成任务”,而这些代码需要付出更多的努力来编写。

    另外,由于额外的复杂性,更改内容也会变得更加困难,因为更多的代码行依赖于域的可见接口。这与您可能想要实现的目标正好相反,因为解耦应该有助于使系统更易于理解和维护(除其他外)。

        3
  •  1
  •   Mark Seemann    14 年前

    你可能真的需要。如果域模型引用接口库,则不能引用域模型 从…起 接口库,因为这将创建一个循环引用。

    硬耦合 在接口和域模型之间。这意味着任何实现或引用接口的人都会引用域模型。你可能不想那样。

    我明确建议您从那些希望与接口一起使用的域对象中提取接口。

    如果你已经有一个叫做 Foo ,然后提取和接口 IFoo 并在其他界面中使用:

    public interface IMyService
    {
        public IBar DoStuff(IFoo foo);
    }
    

    松散耦合 ,这是件好事。它使您的代码更易于维护,更能适应变化。

    提取接口时,请记住必须执行 深抽 .

    如果 看起来像这样

    public class Foo
    {
        public Baz Baz { get; }
    }
    

    public interface IFoo
    {
        IBaz Baz { get; }
    }
    
    public interface IBaz {}
    

    (如果您使用不同的语言编写,请为C代码道歉…)

        4
  •  1
  •   Jeff Sternal    14 年前

    如果 GeneratePdfFromTiff 只是款待 DocumentInfo 就像一个 parameter object 文档信息类没有任何逻辑,它应该只是一个可公开访问的类型。