我在设计一个将领域驱动设计原则与REST相结合的应用程序的架构时遇到了问题。对我来说,这里最大的问题是,域只是接口、规范和响应实体。当然,我可以随意地改变这个公共层,但现在这就是我的想法。我需要这个公共层,因为我希望能够将许多实现中的一个插入到基于域的接口上。
所以它来了:
选项1:我可以将封装和REST与经典对象(只有公开行为的公共方法和@JsonProperty注释的私有字段)结合起来,但是我需要接口(或者我可以使用抽象类),而且您不能在那里拥有私有继承的字段.
选项2:我可以使用@JsonProperty注释的公共getter,但这会破坏封装
选项3:所以我在这里认为最好的是创建不可变的值对象,这些对象将在公共层中实现(如果可以说这组公共字段是实现的话),并且将用作域对象上调用的特定方法的输入和输出。这是个不错的选择吗?我不知道…它似乎工作得很好,没有制动封装原理
我想这基本上解释了我的问题。我认为REST的好处是使用Restlet对象,但让我把注意力集中在Restlet对象上是个问题,这些对象实际上是由不同的实现类…实现的接口
我正在附加一些基本的架构图,也许它会帮助您理解我的问题:

发布于 2014-11-02 20:46:04
我向一位建筑师朋友提出了这个问题,他给我写了这样的话:
让我们想想什么是休息?REST只是一个表示层,它在系统上公开一个视图。它已经对系统及其表示进行了区分(系统边界),我们在这里所拥有的是不同责任的经典问题。我深信“价值是制度的界限”。我不会公开域对象,而是创建值对象,这些对象从域对象转换到域对象。这意味着创建大量的值对象,这些对象表示REST层的单个资源。当然,如果您在Java世界中,它意味着使用getter和setter创建类,但这绝对值得。我可能听起来像法西斯主义者,但我会在域和它的表示之间画出清晰的边界,您只需要很好的映射层(其中有很多),但我不希望在JAXRS端点(资源)中看到域对象。通过这种方式,您可以在您和其他用于BPM的第三方框架之间创建防冲突层,因此简而言之,这意味着这些框架的升级和更改将在您的控制之下。因此,我认为您的方向是正确的,但是不会在JAXRS中使用域类,而是创建值对象。
我需要建立以下几个层次。BPM引擎->公共接口(在我看来类似于DDD的策略) -> VO对象是由根聚合构建的(您需要一种对这些对象进行因子化的方法),VO应该有JSON映射注释,而不是访问根聚合的公共接口-> JAXRS,从它们获得VO可以实现映射的魔力。
因此,由于这一点,您可以有稳定的接口,您不想重建您的休息层,每次系统内的变化。因此VO在这里隐藏您的内部接口(公共接口)的变化。如果我错了,纠正我,但你想要创造一种共同的最低分母的BPM引擎,有相同的模式,尽管不同的激活和jBPM模型。
我确实认为JAXRS应该是非常薄的层,在我工作的应用程序中,在几个地方我们开始添加一些逻辑,你知道最后期限,在一天结束时,当人们不知道在JAXRS中应用了一些额外的规则时,重构是一场噩梦。最后,我们移到模型中,JAXRS只访问聚合根/实体,请求VO并返回它。
发布于 2014-11-01 15:48:43
在我的一个更复杂的企业应用程序上,我基本上拥有相同的架构。为此,我创建了"JAXB值对象“,使用JAXB (如果您愿意的话,+jackson)注释定义了我希望从JAX端点看到的XML/JSON格式。实际上,我使用了适配器模式,这样就可以将这些值对象作为实现处理,并在这些值对象上添加一个工厂方法,这样我就可以根据需要进行复制(有时是深度复制)。与#3不同的是,我没有使JAXB值对象不可变(尽管接口看起来是不可变的),因为JAXB真的不喜欢这样。如果我将这些JAXB值对象传递给另一个组件(我没有),我将首先执行一个防御副本。
除了保持围绕接口构建的域( JAXB确实不喜欢的东西)(这对于您提到的不同实现非常重要)之外,它还允许我在需要定义不同的“视图”时定义不同的JAXB值对象。
https://stackoverflow.com/questions/26690847
复制相似问题