应用系统-业务逻辑写入在分层结构中Service层

       近日,关于我们某同学在研发过程中一些设计问题,再次回归老生常谈的问题:业务逻辑写在哪儿一层? 过去二十年软件开发过程中,大部分开发者喜欢使用存储过程(SP),用SP解决一系列业务处理过程,在信息系统中时常听到有SP的存储。各大数据库厂商也对存储过程支撑较好。我过去已经反思过,是不是可以使用SP中直接构建HTML的字符串整合数据返回,实际上是可以做到的《Generating HTML from SQL Server Queries》。但真实软件系统,我们可能不这么做。系统各层职责也不清楚,谁负责 数据存储,数据展现,数据构建?本身前端需要完成的渲染VIEW事项,被数据库完成了?这样的弊端似乎更多。

        如下经典的分层架构:

image

表示层:表示层处理HTTP请求,将JSON参数转换为对象,并对请求进行身份验证,然后将其传输到业务层。简而言之,它由视图组成,即前端部分。

业务层:业务层处理所有的业务逻辑。它由服务类组成,并使用数据访问层提供的服务。它还执行授权和验证。

持久化层:持久化层包含所有的存储逻辑,并将业务对象从数据库行中翻译出来。

数据库层:在数据库层中执行CRUD(创建、检索、更新、删除)操作。


对应我们JAVA中工程结构是这样:

当时只有3层:表示层、持久层和服务层。服务层几乎处理了所有事情。

image

image



为了后期演化


1) 国产化数据库适配
2) 业务逻辑的可测试性
3) SQL可维护性较弱,不同数据库SQL少许差别
4) 工程转型微服务架构


原因

可扩展性:业务逻辑在service层 计算可以伸缩扩展,而在在sql中依赖 数据库server自己计算资源,是有限的,不容易扩展。数据量多时容易产生 slow log, 进而SQL优化,mysql数据库本身有瓶颈。
可测试性:SQL 脚本少一个分号,只有整个工程启动时,调用这个接口时才知道。在service层我们可以用单元测试。
系统支撑国产化数据库,ARM架构
单元测试 关注于 service层,不访问数据库,如业务逻辑在SQL 则测试覆盖不到。接口测试代价较高。单元测试成本最低。


回顾常见问题

1. 业务逻辑写入SQL是指 a字符转换处理,b字符连接,c字段拼接,d自定义函数,e存储过程
f多表join,

如这样的SQL,使用GROUP_CONCAT

SELECT project.id AS id,
project.project_name AS project_name,
GROUP_CONCAT(DISTINCT param.param_name SEPARATOR '、') AS project_param,
GROUP_CONCAT(DISTINCT method.standard_name, ' ', method.standard_number SEPARATOR '、') AS project_method,
GROUP_CONCAT(DISTINCT domain.domain_code SEPARATOR '、') AS project_domain,
project.status AS status,
project.create_time AS create_time,
project.update_time AS update_time,
GROUP_CONCAT(DISTINCT link_person1, ':', link_phone1, ';', link_person2, ':', link_phone2) AS link
FROM t_ab_project AS project
LEFT JOIN t_ab_project_domain AS domain ON domain.project_id = project.id
LEFT JOIN t_ab_project_param AS param ON param.project_id = project.id
LEFT JOIN t_ab_project_method AS method ON method.project_id = project.id

事实情况在程序中处理有更高伸缩性。

2. 避免SQL中Join基础表


将业务逻辑置于应用程序中,而非数据库中

      业务逻辑是应用程序的核心,它定义了应用程序如何执行其任务。但是,业务逻辑应该放在哪里?许多开发人员会自然而然地将其置于数据库中。毕竟,数据库是数据的源头,而业务逻辑往往涉及到数据处理。然而,这种做法是有问题的。将业务逻辑置于应用程序中,而非数据库中,是更好的做法。以下是为什么:

      数据库的主要职责是存储和保护数据。它们经过优化,以确保数据的完整性和可靠性。然而,它们并不是为执行复杂业务规则而设计的。将业务逻辑置于数据库中可能会导致混乱和难以维护的代码。

      另一方面,应用程序是为处理业务逻辑而构建的。应用程序可以更容易地处理复杂的业务规则和数据验证。此外,应用程序可以提供更好的用户体验,因为它们可以更方便地与用户界面和其他系统集成。

将业务逻辑置于应用程序中也可以提高代码的可重用性。如果多个应用程序需要使用相同的业务逻辑,则可以将其封装在共享库中,而不是在每个应用程序中重复相同的代码。

      当然,这并不是说数据库不应该参与业务逻辑的处理。事实上,数据库触发器和其他存储过程可以在某些情况下非常有用。但是,这些应该作为应用程序业务逻辑的补充,而不是替代。将业务逻辑置于应用程序中,而非数据库中,是更好的做法。这可以提高代码的可维护性、可重用性和整体质量。


将业务逻辑放在数据库中的优缺点

优点

  1. 便于数据访问:将业务逻辑放在数据库中,可以方便地访问和操作数据。这可以减少网络延迟和数据传输的开销,提高应用程序的性能。
  2. 原子性保证:数据库事务可以确保数据的原子性,即在事务执行期间,数据要么全部更新,要么全部回滚。这可以保证数据的一致性。
  3. 简化应用程序逻辑:将业务逻辑放在数据库中,可以减轻应用程序的负担,使其专注于用户界面和用户交互,而不需要处理复杂的数据处理逻辑。

缺点

  1. 难以维护:将业务逻辑放在数据库中可能会导致代码混乱和难以维护。数据库不是为处理复杂业务规则而设计的,因此可能会使代码变得更加复杂和难以理解。
  2. 缺乏可重用性:如果多个应用程序需要使用相同的业务逻辑,将其放在数据库中可能会导致代码重复和难以维护。相反,将业务逻辑放在应用程序中,可以将其封装在共享库中,提高代码的可重用性。
  3. 难以测试:对数据库中的业务逻辑进行测试可能会比较困难,因为需要模拟数据库环境,并确保测试数据与生产数据一致。

结论

  1. 将业务逻辑放在数据库中是有优缺点的,需要根据具体情况来决定是否合适。在以下情况下,将业务逻辑放在数据库中可能是合适的:
  2. 数据访问频繁,需要高性能的应用程序。
  3. 需要确保数据的原子性和一致性。
  4. 业务逻辑相对简单,不需要太多的代码重用。

然而,在大多数情况下,将业务逻辑放在应用程序中可能是更好的选择,因为这样可以提高代码的可维护性和可重用性,并降低测试的难度。

工程师的设计能力区别在于是否全局性思考性能,可测试性,安全,可扩展性等质量特性。


更多参考:

《Is SQL a good place for business logic?》

《Domain Logic and SQL》
《Put business logic in the application, not the database》



今天先到这儿,希望对云原生,技术领导力, 企业管理,系统架构设计与评估,团队管理, 项目管理, 产品管管,团队建设 有参考作用 , 您可能感兴趣的文章:
构建创业公司突击小团队
国际化环境下系统架构演化
微服务架构设计
视频直播平台的系统架构演化
微服务与Docker介绍
Docker与CI持续集成/CD
互联网电商购物车架构演变案例
互联网业务场景下消息队列架构
互联网高效研发团队管理演进之一
消息系统架构设计演进
互联网电商搜索架构演化之一
企业信息化与软件工程的迷思
企业项目化管理介绍
软件项目成功之要素
人际沟通风格介绍一
精益IT组织与分享式领导
学习型组织与企业
企业创新文化与等级观念
组织目标与个人目标
初创公司人才招聘与管理
人才公司环境与企业文化
企业文化、团队文化与知识共享
高效能的团队建设
项目管理沟通计划
构建高效的研发与自动化运维
某大型电商云平台实践
互联网数据库架构设计思路
IT基础架构规划方案一(网络系统规划)
餐饮行业解决方案之客户分析流程
餐饮行业解决方案之采购战略制定与实施流程
餐饮行业解决方案之业务设计流程
供应链需求调研CheckList
企业应用之性能实时度量系统演变

如有想了解更多软件设计与架构, 系统IT,企业信息化, 团队管理 资讯,请关注我的微信订阅号:

MegadotnetMicroMsg_thumb1_thumb1_thu[2]

作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 该文章也同时发布在我的独立博客中-Petter Liu Blog。

posted on 2023-10-14 09:40  PetterLiu  阅读(163)  评论(0编辑  收藏  举报