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

我学习了spring及其分层结构(控制器,服务和dao)

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

现在我很困惑如何利用这些分层结构来利用优秀的OOPS实践 ( 如此 )来制作一个大项目(现实世界有更复杂的业务逻辑,然后通常提供示例应用程序)。 我还想使用这些spring事务和框架提供的其他function。 有些人可以帮我解决这个问题,或者参考开源项目来澄清我的疑问。

简而言之

分层体系结构将简化代码的可维护性和一致性,当它变得庞大而复杂时。

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

  • 封装 – 特定于域模型的业务逻辑应该在其中。
  • 抽象 – 在抽象中编写公共业务逻辑的同时,根据服务分组隔离接口。
  • inheritance – 在绘制域对象时使用
  • 多态性 – 当您想要更改子模型的业务逻辑时,还有inheritance。

详细地

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

以下描述适用于任何需要在Spring(或任何其他框架)中理解和使用分层项目结构的开发人员。

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


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

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

在ERP示例中,您可以获得模型: CustomerOrderCustomerOrderLine

这还包含子域对象的en-capsuled逻辑和self的域逻辑。 例如, CustomerOrderLineCustomerOrderLine的子项。 没有父母,孩子就不能存在。 因此,父母将完全控制在其中构建孩子。 即业务逻辑封装。 。 即: Add CustomerOrderLineRemoveCustomerOrderLine等。当谈到自域逻辑, ApproveCustomerOrderRejectCustomerOrder等。


2.数据访问层 – 存储库

除了使用SELECT, INSERT, UPDATE and DELETE SQLs包含对数据库的简单CRUD。 您可以在Spring中使用存储库模式以及Spring Data JPA

注意:除非您的逻辑是高度数据密集的,否则不要在此层中编写任何复杂的逻辑

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

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

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


3.服务层

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

因此,为了保持一致性并实现安全性 ,我宁愿所有在域模型中编写的业务逻辑都包含在这一层。

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

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

其他复杂业务逻辑的例子

如果要为供应商创建Purchase Order ,则在下达Customer Order时。

然后,这可以通过创建一个名为SupplyChainService的服务来完成,该服务使用Spring AOP绑定到CustomerOrderService.ReleaseCustomerOrder


4.控制器

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

在ERP系统中,您可以在此处为客户订单表单编写控制器,以输入数据并保存以创建新的客户订单。

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

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

Spring应用程序设计和OOD不是互斥的。

典型的Spring(MVC)应用程序具有以下结构:

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

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

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

  1. 每个actor的一个视图( @Controller
  2. 每个用例一个@Service
  3. 每个域类有一个@Repository和一个@Component

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

您正在尝试理解可以一起互操作的两个不同概念。

分层架构

层架构是业界的架构风格之一。 在这里我们有单独的层来做特定的逻辑。 示例我们有表示层,业务层和数据服务层。 这称为应用程序的水平切片。 还有其他架构风格,如面向服务/基于组件的体系结构,其中应用程序是垂直切片的。

假设您有自动预订流程。 通常,如果你采用分层架构设计(水平切片),那么我们有不同的层来完成所需的工作。 但是当涉及垂直切片时,我们将应用程序的不同实体识别为预订,客户管理,基金管理。 我们将实现这些组件,并相互通信以构建我们的预订应用程序。 这里需要记住的是内部组件可以使用相同的分层架构。

OOPS概念

OOPS概念可帮助您以面向对象的方式设计应用程序。 一旦确定了体系结构样式,就必须以可扩展的方式实现应用程序,并且可以轻松维护。 所以,他们有不同的实施方法。 OOPS就在他们身上。 它提出了一些设计原则,可帮助您以更好的方式实现应用程序

见SOLID

我想,你在这里问一个错误的问题。 分层体系结构本质上不是面向对象的,因此,虽然使用(某些)面向对象的实践是可能的,甚至是可取的,但它本身不应该是目标。 它类似于询问我如何使用最佳的卡车驾驶练习来骑自行车。

为什么我说分层架构不是面向对象的? 嗯,正如我们所知,区分面向对象设计有三个原则:封装,inheritance和多态。

虽然最后两个可能存在也可能不存在,但根据您的设计选择,分层架构几乎封装相反 :根据这种方法的本质,您明确地将数据(“DTO”)与逻辑分开(“服务”)。

不要误解我,这种方法不是面向对象的事实并不意味着它有任何问题。 反之亦然,“面向对象”并不是“好”的同义词,它是程序员工具箱中的众多工具之一,并且与任何工具一样,更适合解决某些问题而不是其他工具。

分层架构是一种很好的设计模式,可以成功地用于解决许多现实工程问题。 它有自己的一套可以并且应该使用的最佳实践,虽然这个集合可能与OOP的对应部分有一些交叉点,但这两者肯定不相同。