如何使用弹簧的分层架构,同时仍然遵循面向对象的结构?

2022-09-01 16:42:35

我学习了弹簧及其分层结构(控制器,服务和道)

@Controller("userController")

@service("userService")
@Transactional(     propagation = Propagation.REQUIRED,     isolation = Isolation.DEFAULT,      readOnly = true)

@Repository("userDAO")

现在我很困惑,我如何利用良好的OOPS实践(像这样)和这些分层结构来制作一个大项目(现实世界的业务逻辑比通常提供的示例应用程序更复杂)。我还想使用这些弹簧交易和框架提供的其他功能。有人可以帮我解决它或参考开源项目,这澄清了我的疑问。


答案 1

简而言之

分层架构在变得庞大而复杂时,只会简化代码的可维护性和一致性。

要记住的事实是,在进行实现之前要进行适当的软件设计。

  • 封装 - 特定于域模型的业务逻辑应位于其中。
  • 抽象 - 根据服务的分组隔离接口,同时在抽象中编写通用业务逻辑。
  • 继承 - 在起草域对象时使用
  • 多态性 - 当您想要更改子模型的业务逻辑时,与继承一起。

详细地

下面我尽力为这次讨论提供一个ERP应用程序的例子。希望ERP是一个足以查看业务逻辑复杂性的大项目

下面的描述是给任何需要一个想法来理解和使用Spring(或任何其他框架)中的分层项目结构的开发人员。

但请注意,这些不是要遵循的规则,而是要使用的最佳实践。:)


1. 数据访问层 - 模型/域对象

这包含实际表到类的映射。

在 ERP 示例中,您可以在此处获取模型:、CustomerOrderCustomerOrderLine

这也包含子域对象的包罗包逻辑和 self 的域逻辑。例如,是 的子项。没有父项,子项就不能存在。因此,父母将完全控制在其中建立孩子。即业务逻辑封装。即:等。当涉及到自域逻辑时,等。CustomerOrderLineCustomerOrderAdd CustomerOrderLineRemoveCustomerOrderLineApproveCustomerOrderRejectCustomerOrder


2. 数据访问层 - 存储库

这只包含简单的 CRUD 到数据库与 .您可以在 Spring 中使用存储库模式以及 .SELECT, INSERT, UPDATE and DELETE SQLsSpring Data JPA

关键提示:不要在此层中编写任何复杂的逻辑,除非您的逻辑是高度数据密集型的

在这种情况下,您可能必须编写一个或多个函数来执行复杂的查询语句。(最好在JPQL)

在 ERP 示例中,这是您为 、 编写逻辑的地方。GetCustomerOrdersGetCustomerOrderByCustomerGetCustomerOrderLinesGetOrderByStatus

简单来说,此层定义了应用程序将如何与外部实体(如数据库)进行通信。


3. 服务层

这是您应该放置涉及多个未连接(不是子 - 父)域模型的复杂业务逻辑的地方。这些将在 Web 控制器和 Rest API 控制器中重用。

因此,为了保持一致性并实现安全性,我希望所有业务逻辑(即使是在域模型中编写的业务逻辑)都包含在此层。

在ERP示例中,这是您编写逻辑或包装在域模型中编写的逻辑的地方。例如。。。CreateCustomerOrderListCustomerOrderApproveCustomerOrderLineReleaseCustomerOrder

如果这些逻辑应该与其他模型逻辑一起执行,那么这些逻辑也应该在服务层中按顺序调用。例如。

复杂业务逻辑的杂项示例

如果要为您的供应商创建一个,当发布时。Purchase OrderCustomer Order

然后,这可以通过创建一个名为“使用 Spring AOP 绑定到 .在微服务设计中,这可以通过域微服务发布到队列的事件来完成,并由域微服务使用SupplyChainServiceCustomerOrderService.ReleaseCustomerOrderSupply chainCustomer Order


4. 控制器

控制器可以分为两类,即:Web 控制器和 REST 控制器。不应在此层中实现任何业务逻辑,因为在 Web 和 API 级别中调用时可能需要相同的逻辑。

在 ERP 系统中,这是您将为客户订单表单编写控制器以输入数据并保存以创建新的客户订单的位置。

在这里,您还将创建一个 API 控制器(如 REST),以通过移动应用程序或 Windows 客户端创建客户订单。

感谢SO社区向我展示了我在这个答案中没有涵盖OOP原则的领域

编辑


当微服务不太主流时,这是一个答案。虽然它回答了OOP概念,但也要研究基于CQRS的设计,因为它在现代基于微服务的架构中更为常见。无论哪种方式,您都可以合并OOP概念,而不管您使用哪种软件架构模式。


答案 2

弹簧应用设计和OOD并不相互排斥。

典型的弹簧(MVC)应用具有以下结构:

  1. 一个或多个类。这些是应用程序的入口点。它们不应包含任何业务逻辑。尽管有这个名字,我还是将它们标识为MVC(模型 - 视图 - 控制器)中的V@Controller)
  2. 一个或多个类。这是您开发业务逻辑 (BL) 的地方。将BL放在这里的好处之一是它可以被多个控制器重用(例如,通过a和a)。它们是 MVC 中的 C@Service@Controller@RestController
  3. 一个或多个类,您可以在其中实现持久性层(数据库,内存中,等等)。此外,还可以实现一组描述域对象的 s 类。这些是MVC中的M@Repository@Component
  4. 无法在 MVC 模式中映射的其他类,如 和其他 Spring 配置/管理类。@Configuration@ControllerAdvice

在设计这些对象中的每一个时,您可以遵循您喜欢的任何OOD方法。

在你提到的OOD示例中,我会像这样设计我的应用程序:

  1. 每个参与者一个视图 ()@Controller
  2. 每个用例一个@Service
  3. 每个域类一个和一个@Repository@Component

编辑:你可以在这里找到我为大学写的一个示例项目。它通过一个额外的层(在@Controller和@Service之间)实现了我在前三点中解释的内容,因为需要最小化对C层的依赖性。这些概念仍然适用。