我学习了spring及其分层结构(控制器,服务和dao)
@Controller("userController") @service("userService") @Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = true) @Repository("userDAO")
现在我很困惑如何利用这些分层结构来利用优秀的OOPS实践(如此)来构建一个大项目(现实世界中有更复杂的业务逻辑,然后通常提供示例应用程序).我还想使用这些spring事务和框架提供的其他功能.有些人可以帮我解决这个问题,或者参考开源项目来澄清我的疑问.
简而言之
分层体系结构将简化代码的可维护性和一致性,当它变得庞大而复杂时.
要记住的事实是在执行之前要进行适当的软件设计.
封装 - 特定于域模型的业务逻辑应该在其中.
抽象 - 在抽象中编写公共业务逻辑的同时,根据服务分组隔离接口.
继承 - 在绘制域对象时使用
多态性 - 当您想要更改子模型的业务逻辑时,还有继承.
详细地
下面我正在尽力为这次讨论提供一个ERP应用程序示例.希望ERP是一个足以查看业务逻辑复杂性的大项目.
以下描述适用于任何需要在Spring(或任何其他框架)中理解和使用分层项目结构的开发人员.
但请注意,这些不是要遵循的规则,而是要使用的最佳实践.:)
这包含实际表到类的映射.
在ERP为例,这是你在哪里得到的模型:
CustomerOrder
,CustomerOrderLine
这还包含子域对象的en-capsuled逻辑和self的域逻辑.例如,他
CustomerOrderLine
是一个孩子CustomerOrder
.没有父母,孩子就不能存在.因此,父母将完全控制在其中构建孩子.即业务逻辑封装..即:Add CustomerOrderLine
,RemoveCustomerOrderLine
等等.而当谈到自己的域逻辑,ApproveCustomerOrder
,RejectCustomerOrder
等.
这只包含简单的CRUD到数据库SELECT, INSERT, UPDATE and DELETE SQLs
.您可以在Spring中使用存储库模式Spring Data JPA
.
注意:除非您的逻辑是高度数据密集的,否则不要在此层中编写任何复杂的逻辑
在这种情况下,您可能必须编写一个或多个函数来执行复杂的查询语句.(最好在JPQL
)
在ERP为例,这是你写的逻辑的地方
GetCustomerOrders
,GetCustomerOrderByCustomer
,GetCustomerOrderLines
,GetOrderByStatus
简单来说,该层定义了应用程序如何与外部实体(如数据库)进行通信.
3.服务层
在这里,您应该放置涉及多个未连接(非子 - 父)域模型的复杂业务逻辑.这些将在Web控制器和Rest API控制器中重用.
因此,为了保持一致性并实现安全性,我宁愿所有在域模型中编写的业务逻辑都包含在这一层.
在ERP例子中,这是您编写逻辑或包装在域模型中编写的逻辑的地方.例如
CreateCustomerOrder
,ListCustomerOrder
,ApproveCustomerOrderLine
,ReleaseCustomerOrder
,...
如果这些逻辑应该与其他模型逻辑一起执行,那么也应该在服务层内的序列中调用它们.例如.
其他复杂业务逻辑示例
如果您想
Purchase Order
为供应商创建一个,当它Customer Order
被释放时.
然后,这可以通过SupplyChainService
使用Spring AOP 创建一个名为binded 的服务来完成CustomerOrderService.ReleaseCustomerOrder
.
4.控制器
控制器可以分为两类,即:Web控制器和REST控制器.在该层中不应该实现业务逻辑,因为在Web和API级别中调用可能需要相同的逻辑.
在ERP系统中,您可以在此处为客户订单表单编写控制器,以输入数据并保存以创建新的客户订单.
这将是您还将创建一个API控制器(如REST)以通过移动应用程序或Windows客户端创建客户订单的位置.
感谢SO社区向我展示了我在这个答案中没有涉及OOP原则的领域
Spring应用程序设计和OOD不是互斥的.
典型的Spring(MVC)应用程序具有以下结构:
一个或多个@Controller
班级.这些是您的应用程序的入口点.它们不应包含任何业务逻辑.尽管名称我将它们识别为MVC中的V(模型 - 视图 - 控制器)
一个或多个@Service
班级.这是您开发业务逻辑(BL)的地方.将BL置于此处的好处之一是它可以被多个控制器(例如a @Controller
和a @RestController
)重用.他们是MVC 中的C.
一个或多个@Repository
类,您可以在其中实现持久层(数据库,内存中,等等......).此外,您可以实现一组@Component
描述域对象的类.这些是MVC 中的M.
您无法在MVC模式中映射的其他类@Configuration
,@ControllerAdvice
以及其他Spring配置/管理类.
在设计每个对象时,您可以遵循您喜欢的任何OOD方法.
在你提到的OOD示例中,我会像这样设计我的应用程序:
@Controller
每个演员的一个视图()
一个@Service
为每个用例
每个域类一个@Repository
和一个@Component
编辑:你可以在这里找到我为大学写的一个示例项目.它通过附加层(在@Controller和@Service之间)实现了我在后三点中解释的内容,因为需要最小化对C层的依赖性.这些概念仍然适用.