【问题标题】:Designing application tier - what is your best practice? [closed]设计应用层——你的最佳实践是什么? [关闭]
【发布时间】:2014-03-26 18:03:27
【问题描述】:

设计应用层并非易事。归根结底,在每个项目中,我们都会编写(大量)所谓的 business 方法(有时称为 service 方法,尽管它与服务无关,因为在公共 API 中)执行一些业务逻辑并且通常执行一些数据库/存储操作(通过存储层)。但是设计/组织/命名您的应用程序方法并不像听起来那么简单。人们通常对项目应如何设计应用程序类和方法有规则。我正在寻找一套实用的此类规则来设计应用程序层,所以这里有一些问题:

  1. 类中的分组方法:按返回类型还是?

    例如,更新用户的方法属于类,例如UserService。或者通过某些标准找到用户的方法属于同一类。但是当某些方法适用于多种类型时会发生什么,例如registerUserForCompetition()?这应该在UserService 还是CompetitionService 中? findUserCompetition() 方法的同样问题 - 你会把它放在哪里?

    我经常看到一条规则说这取决于方法的返回类型。在我们的示例中,如果方法返回 User(或用户集合等),它应该属于 UserService

  2. 方法参数:简单类型(基元、字符串...)或实体(例如UserCompetitionRegistration...)?

    这个问题经常被问到,人们通常(统计上:)选择第一种方法,使用简单类型作为服务参数。但是当一个这样的方法在同一资源上调用另一个方法时该怎么办?举个例子:registerUser(userId, competitionId) 可以内部调用checkCompetition(competitionId)。这两种方法都从存储中获取Competition。显然,这会进行两次,因为我们已经有了Competition 对象,我们可以将它用于checkCompetition。那么我们应该添加重载方法,还是应该忽略这一点而只关注缓存机制以防止重复获取?

    另一方面,将完整类型作为参数不是通用规则,因为很多时候不需要完整信息,并且没有理由在您只需要它的 id 时获取完整对象,您可能已经拥有它。

  3. 命名方法:方法名称应该有多详细?

    尤其是查找器方法。我们应该有例如:

    • findCompetition(userId, year)
    • findCompetitionWithVenue(userId, year)(因为每个Competition对象都链接了Venue);或
    • findCompetitionForUserAndYear(userId, year)
    • findCompetitionByUserIdAndYear(userId, year) 或者只是
    • findUserCompetitionForYear(userId, year)?

    当不同条件的数量增加时,很容易将查找器方法名称弄得一团糟,我经常看到这样的规则:find<return-type>By<names-of-parameters> 或类似的。

  4. 您有应用程序类的命名约定吗?

    您的课程名称是否以Service 结尾?您是否将 managersservices 分开,其中 manager 处理实体和服务仅接受简单类型?您是根据功能将所有业务类分组在同一个包中,还是将它们与其他相关类(模型、控制器...)分组在一起?

请分享您注重务实的经验 - 对我而言,这意味着新开发人员可以轻松地找出在哪里可以找到业务方法以及如何编写新方法,这样每个人都会变得更有效率。另外,如果您已经制定了规则,请分享您的团队是如何遵守这些规则的。

【问题讨论】:

标签: java architecture


【解决方案1】:
  1. 按功能对服务进行分组。在同一个包中也应该是控制器,模型的一部分等。有比分层架构更好的方法。试试 DDD。它完美地隔离了功能,更容易找到和更改

  2. 通常最好对客户端隐藏实体(模型)并通过 DTO 和 ValueObjects 与控制器通信。以防万一您将来想更改模型

  3. 它们必须对您的域有意义且一致。如果你的团队说他们不清楚,不要害怕重构。就个人而言,我会使用非原始类型的findCompetition(user, year),因为您可以使用方法重载,但是在调用时您必须使用常量或读取像findCompetition(forUserId(userId), forYear(year)) 这样的启用程序来明确告诉读者您正在调用哪个版本。

  4. 什么是经理?这不代表任何意思。类似于助手、处理程序等。服务包含将 DTO 转换为实体的逻辑,并且该逻辑无法推送到域/实体,因为该逻辑在许多实体上运行。如前所述,我按功能对组件(不仅仅是服务)进行分组,因此我添加了“服务”后缀,因为它可以帮助我快速找到特定包(包含模型、控制器、服务、存储库等)中的逻辑

【讨论】:

  • 你知道任何开源 DDD java 项目(如果可能的话,一些产品)?网上到处都是相当简单的 DDD 示例,我觉得我没有了解完整的情况。
  • 不,我没有任何有用的链接。我同意,网络上有相当简单的项目。我有同样的问题
猜你喜欢
  • 2010-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多