实体-控制-边界模式(Entity-Control-Boundary pattern) -> 如何处理两个实体?

13

前提

我最近阅读/观看了很多Java Champion Adam Bien的文章/视频,他倡导使用古老的更新的实体-控制-边界设计模式JAVA EE >= 6。

利用CDI、EJB 3.1、JPA 2和其他JAVA EE 6功能,此模式应有助于创建更多面向业务的组件,易于单元测试,并基于职责具有更高的关注点分离。

由于我正在使用上述所有功能,而且这种模式听起来非常有趣,因此我正在考察它,以查看ECB是否符合我的下一个项目要求。


我已经得到的

在ECB中,每个逻辑实体都分为三个部分(如果我错了,请纠正我):

  • 一个边界,一种强大的外观,是唯一可从外部访问的类。对于外部(如果我理解正确),我们指的是应用程序之外,例如远程客户端,以及组件包之外,例如应用程序的另一部分;

  • 一个(可选的)控制器,负责某些操作(例如,实体的验证);

  • 一个实体,可以是纯JPA实体,但也可以包含一些内部的装饰/验证/(最小)业务逻辑。

例如,考虑有两个不同的实体(OrangeApple),一个用于对它们进行CRUD的类(FruitsManager)和一个用于对它们执行一些控制的类(FruitsQualityChecker)。

直到昨天,它会像这样(旧方式):

com.foo.bar.business.FruitsService        /* CRUD    */
com.foo.bar.business.FruitsQualityChecker /* CONTROL */
com.foo.bar.model.Orange                  /* ENTITY  */
com.foo.bar.model.Apple                   /* ENTITY  */

使用ECB,我将会有以下操作(新方式):

com.foo.bar.business.oranges.boundary.Oranges       /* CRUD    */ 
com.foo.bar.business.oranges.control.QualityChecker /* CONTROL */
com.foo.bar.business.oranges.entity.Orange          /* ENTITY  */

com.foo.bar.business.apples.boundary.Apples         /* CRUD    */
com.foo.bar.business.apples.control.QualityChecker  /* CONTROL */
com.foo.bar.business.apples.entity.Apple            /* ENTITY  */
然后我可以对每个实体进行CRUD操作和研究,例如使用…
Oranges.findOrangesByPrice(min, max);

主要问题

如何处理跨组件的研究,例如 findFruitsByPrice(min,max)

我应该调用findOrangesByPricefindApplesByPrice并累加结果吗?从哪个类开始,打包在哪里? 如果我有一个搜索页面,有许多条件必须跨越50个实体进行交叉搜索,运行每个实体的50次搜索方法,然后执行插值,听起来非常丑陋,并对性能产生巨大影响。我想我仍然需要一个中心点来执行这种操作。它应该是另一个组件,称为例如Searches,在其边界内调用其他边界吗?这一点目前对我来说还不清楚。


附加问题

在使用基于动作的框架时使用ECB模式有意义吗?还是这种模式仅适用于基于组件的框架?

我正在使用Struts2,这是一个MVC基于动作的框架,而我对JSF2(JAVA EE 6标准,在Adam Bien的大多数演示中使用)不太熟悉,它是一个MVC基于组件的框架;

除了需要以“组件方式”思考架构之外,是否有什么阻止我在业务层上使用ECB模式?

由于Adam Bien的大多数示例中的边界都是REST服务(通常更像是Struts2 Actions的替代品而不是“链条中的新齿轮”),这让我怀疑它是否完全适用于Struts2生态系统。

请发表您的观点。

1个回答

4
据我理解,关于设计模式,“你到目前为止”是正确的。
至于你的“主要问题”,就像其他设计模式一样,你可以简单地引入另一个SuperComponent,它在一些端点(或一个端点,这样它就不会变得过大)中使用。该SuperComponent将以正确的方式执行操作:如果需要,您将使用一些现有的组件,以便性能和代码质量不会受到影响。我的意思是:您可能会编写与特定端点相关的逻辑,而无需关心它是否会返回Oranges AND Apples,从而使单个查询到DB(如果您的领域模型能够做到)。使用其他组件获取这些水果并将它们合并是一种糟糕的设计,无论使用什么设计模式(想象一下您以后会获得Avocados,然后您将不得不编写代码/更正错误,以支持新的水果)。
现在与你的“次要问题”(IMHO)有些相关: ECB对于小项目来说还可以,但对于大项目来说,您可能需要更多层次的结构:
- 只处理用户请求/输入的Web层(我不喜欢我的EJB知道HttpRequest和HttpResponse的想法) - 一个多层应用程序模型,具有DAO层(对于CRUD操作不是必需的,但如果您在多个EJB中使用相同的NamedQuery和5个参数,则为情况)。

+1,好答案。关于超级组件,我猜它应该直接访问其他组件的实体(而不是通过它们的边界),但你有关于它们的打包结构的任何想法吗?例如com.foo.bar.business.fruits.boundary.Fruitscom.foo.bar.business.fruits.something.apples.boundary.Apples,或者除此之外?只是试图按照这种模式的粉丝所想的方式来做正确的事情。 - Andrea Ligios
1
你如何定义包中的事物实际上是Adam Bien的标准,而不是设计模式本身的一部分。我建议首先将它们放在同一个包*.boundary中,然后如果你发现很难找到它们或者很难理解它们的职责,就将它们重构到其他子包中。 - V G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接