我学习了spring及其分层结构(控制器,服务和dao)
@Controller("userController")
@service("userService")
@Transactional( propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = true)
@Repository("userDAO")
现在我很困惑如何利用这些分层结构的优秀的OOPS实践(如this)来制作一个大项目(现实世界有更复杂的业务逻辑然后样本通常提供的申请)。我还想使用这些spring事务和框架提供的其他功能。 有些人可以帮我解决这个问题,或者参考开源项目来澄清我的疑问。
答案 0 :(得分:40)
简而言之
分层架构只会在代码可维护性和一致性变得庞大而复杂时简化。
要记住的事实是在执行之前要进行适当的软件设计。
详细
下面我将尽力为此讨论提供一个ERP应用程序示例。希望ERP是一个足够的大项目来查看业务逻辑的复杂性。
以下描述适用于任何需要在Spring(或任何其他框架)中理解和使用分层项目结构的开发人员。
但请注意,这些不是要遵循的规则,而是要使用的最佳实践。 :)
<小时/> 的 1。数据访问层 - 模型/域对象
这包含实际表到类的映射。
在ERP示例中,您可以在这里获得模型:
CustomerOrder
,CustomerOrderLine
这还包含子域对象的en-capsuled逻辑和self的域逻辑。例如,
CustomerOrderLine
是CustomerOrder
的孩子。没有父母,孩子就不能存在。因此,父母将完全控制在其中构建孩子。即业务逻辑封装。。即:Add CustomerOrderLine
,RemoveCustomerOrderLine
等。当谈到自我逻辑域时,ApproveCustomerOrder
,RejectCustomerOrder
等。
<小时/> 的 2。数据访问层 - 存储库
除了SELECT, INSERT, UPDATE and DELETE SQLs
之外,它只包含对数据库的简单CRUD。您可以在Spring中使用存储库模式以及Spring Data JPA
。
注意:除非您的逻辑数据密集程度很高,否则不要在此图层中编写任何复杂的逻辑
在这种情况下,您可能必须编写一个或多个函数来执行复杂的查询语句。 (最好在JPQL
)
在ERP示例中,这是您为
编写逻辑的地方GetCustomerOrders
,GetCustomerOrderByCustomer
,GetCustomerOrderLines
,GetOrderByStatus
简单来说,该层定义了应用程序如何与外部实体(如数据库)进行通信。
第3。服务层
这是您应该放置涉及多个未连接(非子 - 父)域模型的复杂业务逻辑的地方。这些将在Web控制器和Rest API控制器中重用。
因此,为了保持一致性并实施安全性,我希望所有业务逻辑甚至是在域模型中编写的业务逻辑都会被包含在这一层。
在ERP例子中,这是您编写逻辑或包装在域模型中编写的逻辑的地方。例如
CreateCustomerOrder
,ListCustomerOrder
,ApproveCustomerOrderLine
,ReleaseCustomerOrder
,...
如果这些逻辑应该与其他模型逻辑一起执行,那么这些逻辑也应该在服务层内的序列中调用。例如。
关于复杂业务逻辑的其他示例
如果您想为供应商创建
Purchase Order
,请Customer Order
发布。
然后,可以通过使用Spring AOP绑定到SupplyChainService
来绑定CustomerOrderService.ReleaseCustomerOrder
的服务来完成此操作。
<强> 4。控制器强>
控制器可以分为两类,即:Web控制器和REST控制器。在该层中不应该实现业务逻辑,因为在Web和API级别中调用可能需要相同的逻辑。
在ERP系统中,您可以在此处为客户订单表单编写控制器,以输入数据并保存以创建新的客户订单。
您将创建一个像REST这样的API控制器,通过移动应用程序或Windows客户端创建客户订单。
感谢SO社区向我展示了我在这个答案中没有涉及OOP原则的领域
答案 1 :(得分:8)
Spring应用程序设计和OOD不是互斥的。
典型的Spring(MVC)应用程序具有以下结构:
@Controller
课程。这些是您的应用程序的入口点。它们不应包含任何业务逻辑。尽管名称我将它们标识为MVC中的 V (Model-View-Controller)@Service
课程。这是您开发业务逻辑(BL)的地方。将BL置于此处的一个好处是它可以被多个控制器重用(例如@Controller
和@RestController
)。它们是MVC中的 C 。@Repository
类,您可以在其中实现持久层(数据库,内存中,等等......)。此外,您可以实现一组描述域对象的@Component
类。这些是MVC中的 M 。@Configuration
,@ControllerAdvice
和其他Spring配置/管理类。在设计每个对象时,您可以遵循您喜欢的任何OOD方法。
在你提到的OOD示例中,我会像这样设计我的应用程序:
@Controller
)@Service
@Repository
和一个@Component
编辑:您可以找到我为大学here写的示例项目。它通过附加层(在@Controller和@Service之间)实现了我在后三点中解释的内容,因为需要最小化 C 层的依赖性。这些概念仍然适用。
答案 2 :(得分:4)
我想,你在这里问一个错误的问题。分层体系结构本质上不是面向对象的,因此,尽管使用(某些)面向对象的实践是可能的,甚至是可取的,但它本身不应该是目标。这类似于询问我如何使用最佳卡车驾驶练习骑自行车。
为什么我说分层架构不是面向对象的?嗯,正如我们所知,区分面向对象设计有三个原则:封装,继承和多态。
虽然最后两个可能存在,也可能不存在,但根据您的设计选择,分层架构几乎就是封装的相反:根据这种方法的本质,您明确地将数据分开(“DTO”)来自你的逻辑(“服务”)。
不要误解我,这种方法不是面向对象的事实并不意味着它有任何问题。反之亦然,“面向对象”并不是“好”的同义词,它是程序员工具箱中的众多工具之一,而且,与任何工具一样,它比其他工具更适合解决某些问题。
分层架构是一种很好的设计模式,可以成功地用于解决许多现实工程问题。它有自己的一套可以并且应该使用的最佳实践,虽然这个集合可能与OOP的对应部分有一些交叉点,但这两者肯定不等同。
答案 3 :(得分:4)
您正在尝试理解可以互操作的两个不同概念。
分层架构
层架构是业界的架构风格之一。在这里我们有单独的层来做特定的逻辑。示例我们有表示层,业务层和数据服务层。这称为应用程序的水平切片。还有其他架构风格,如面向服务/基于组件的体系结构,其中应用程序是垂直切片的。
假设您有自动预订流程。通常,如果你采用分层架构设计(水平切片),那么我们有不同的层来完成所需的工作。但是当涉及垂直切片时,我们将应用程序的不同实体识别为预订,客户管理,基金管理。我们将实现这些组件,并相互通信以构建我们的预订应用程序。需要记住的是内部组件可以使用相同的分层架构。
OOPS概念
OOPS概念可帮助您以面向对象的方式设计应用程序。一旦确定了体系结构样式,就必须以可扩展的方式实现应用程序,并且可以轻松维护。所以,他们有不同的实施方法。 OOPS就在他们身上。它提出了一些帮助您以更好的方式实现应用程序的设计原则
请参阅SOLID