单体工程结构

本文主要说明下单体项目的工程结构如何设计,目前业界存在两种主流的应用工程结构:一种是阿里推出的《Java开发手册》中推荐的,另外一种是基于DDD(领域驱动设计)推荐的。下面我们来看下两种工程结构是怎样的。

一、 基于阿里《Java开发手册》的分层结构

阿里巴巴的官方文档的分层主要是分为如下这些层:

开放API 层:可直接封装Service 接口暴露成RPC 接口;通过Web 封装成http 接口;网关控制层等。
终端显示层:各个端的模板渲染并执行显示的层。当前主要是velocity 渲染,JS 渲染,JSP 渲染,移动端展示等。
Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
Service 层:相对具体的业务逻辑服务层。
Manager 层:通用业务处理层,它有如下特征:1)对第三方平台封装的层,预处理返回结果及转化异常信息,适配上层接口。2)对Service 层通用能力的下沉,如缓存方案、中间件通用处理。3)与DAO 层交互,对多个DAO 的组合复用。
DAO 层:数据访问层,与底层MySQL、Oracle、Hbase、OB 等进行数据交互。
第三方服务:包括其它部门RPC 服务接口,基础平台,其它公司的HTTP 接口,如淘宝开放平台、支付宝付款服务、高德地图服务等。
外部数据接口:外部(应用)数据存储服务提供的接口,多见于数据迁移场景中。

调用关系如下:

涉及到的领域模型如下:

DO(Data Object):此对象与数据库表结构一一对应,通过DAO 层向上传输数据源对象。
DTO(Data Transfer Object):数据传输对象,Service 或Manager 向外传输的对象。
BO(Business Object):业务对象,可以由Service 层输出的封装业务逻辑的对象。
Query:数据查询对象,各层接收上层的查询请求。注意超过2 个参数的查询封装,禁止使用Map 类来传输。
VO(View Object):显示层对象,通常是Web 向模板渲染引擎层传输的对象

基于这样的规范我创建了一个demo工程的目录,下面我来解释下这个结构

├─src
│  ├─main
│  │  ├─java
│  │  │  └─com
│  │  │      └─demo
│  │  │          ├─client           --第三方服务:调用第三方服务
│  │  │          │  ├─model         --模型对象
│  │  │          │  └─service       --接口
│  │  │          ├─controler        --终端显示层
│  │  │          │  ├─request       --请求对象
│  │  │          │  ├─response      --响应包装对象
│  │  │          │  └─vo            --不同接口显示层对象
│  │  │          ├─dao              --DAO 层
│  │  │          │  ├─config        --数据库的配置文件
│  │  │          │  ├─dbclient      --与底层MySQL、Oracle、Hbase等进行数据交互的文件
│  │  │          │  ├─query         --数据查询对象
│  │  │          │  ├─do            --此对象与数据库表结构一一对应
│  │  │          │  ├─serializer    --序列化相关  
│  │  │          │  ├─sharding      --分库分表类目
│  │  │          │  └─utils         --一些公共类
│  │  │          ├─facede           --开放API 层:对外封装的Service接口暴露成RPC接口
│  │  │          │  ├─constant      --常量
│  │  │          │  ├─model         
│  │  │          │  ├─request       --请求对象
│  │  │          │  └─service       --接口层
│  │  │          ├─job              --开放API 层:处理job工作           
│  │  │          │  └─model         --数据传输对象
│  │  │          ├─manager          --Manager 层
│  │  │          │  └─dto           
│  │  │          ├─mq               --开放API 层:处理mq工作
│  │  │          │  ├─config
│  │  │          │  ├─consumer      --处理消费者工作
│  │  │          │  ├─model
│  │  │          │  └─publish       --处理生产者工作│  │  │          ├─service          --Service 层
│  │  │             ├─schedule      --处理定时任务
│  │  │          │  ├─bo
│  │  │          │  └─dto
│  │  │          └─web              --Web 层
│  │  │              ├─filter       --过滤层
│  │  │              └─Interceptor  --拦截器层
│  │  └─resources                   --资源文件
│  │      └─META-INF
│  └─test                           --针对每个层次文件的测试文件
│      └─java
│          └─com
│              └─demo
│                  ├─client
│                  │  ├─model
│                  │  └─service
│                  ├─controler
│                  │  ├─request
│                  │  ├─response
│                  │  └─vo
│                  ├─dao
│                  │  ├─config
│                  │  ├─dbclient
│                  │  ├─do
│                  │  ├─query
│                  │  ├─sharding
│                  │  ├─serializer
│                  │  ├─sharding
│                  │  └─utils
│                  ├─facede
│                  │  ├─constant
│                  │  ├─model
│                  │  ├─request
│                  │  └─service
│                  ├─job
│                  │  └─model
│                  ├─manager
│                  │  └─dto
│                  ├─mq
│                  │  ├─config
│                  │  ├─consumer
│                  │  ├─model
│                  │  └─publish│                  ├─service
│                  │  ├─schedule
│                  │  ├─bo
│                  │  └─dto
│                  └─web
│                      ├─filter
│                      └─Interceptor
└─

可能上面的信息比较多看者比较不清晰,下面我们用列表来展示下:

层次

包名

对象名规范

备注

测试层

test

对象名规范同各层级

开放API 层

job、mq、

model

model为模型对象

终端显示层

controler

request、response、vo

Web 层

web

Service层

service

bo、dto

Manager层

manager

dto

DAO层

dao

query、do

第三方服务

client

model

二、 基于DDD(领域驱动设计)的分层结构

DDD(领域驱动设计,Domain-Driven Design)的分层结构主要是为了更好地组织和分离关注点,确保业务逻辑的清晰性和可维护性。DDD 的分层结构通常包括以下几个层次:

  1. 用户接口层(User Interface Layer):
    • 这一层主要负责与前端应用或其他外部服务的交互。
    • 它会接收和响应外部请求,并将业务逻辑的结果展示给用户。
    • 这一层不应该包含任何业务逻辑,主要是数据的展示和接收。
  1. 应用服务层(Application Service Layer):
    • 这一层是DDD中的业务编排层,它协调领域层中的各个组件来执行特定的业务用例。
    • 应用服务层通常包含服务组合、编排、安全认证、权限校验、事务控制等功能。
    • 应用服务层可能会调用多个领域服务来完成一个复杂的业务操作。
  1. 领域层(Domain Layer):
    • 这是DDD中的核心层,包含了业务领域的所有核心逻辑和概念。
    • 领域层主要由实体(Entity)、值对象(Value Object)、领域服务(Domain Service)和领域事件(Domain Event)等组成。
    • 实体和值对象表达了业务概念,而领域服务则实现了复杂的业务规则。
  1. 基础设施层(Infrastructure Layer):
    • 这一层提供了技术实现和支撑服务,如数据库访问、消息传递、缓存等。
    • 基础设施层为上层提供了技术细节的实现,隐藏了底层技术的复杂性。
    • 基础设施层通常实现了领域层中定义的接口和协议,使得上层可以专注于业务逻辑。

DDD的分层结构遵循了依赖倒置原则(Dependency Inversion Principle),即高层模块不应该依赖于低层模块,它们都应该依赖于抽象。此外,DDD的分层结构还强调了领域层的独立性和核心地位,确保业务逻辑的稳定性和可重用性。四个层次调用关系如下:

根据这样的架构我们来理解下和工程结构的映射关系大致如下:

具体到业务流程中是这样的:

基于ddd,我们也可以根据这样的架构来设计一个工程结构,如下:

├─com.company.microservice
├─com.company.microservice
│    │ 
│    ├─apis   API接口层 
│    │    └─controller       控制器,对外提供(Restful)接口
│    │ 
│    ├─application  应用层
│    │    ├─model            数据传输对象模型及其装配器(含校验)
│    │    │    ├─assembler   装配器,,实现模型转换eg. apiModel<=> domainModel
│    │    │    └─dto         模型定义(含校验规则)      
│    │    ├─service          应用服务,非核心服务,跨领域的协作、复杂分页查询等
│    │    ├─task             任务定义,协调领域模型
│    │    ├─listener         事件监听定义
│    │    └─***              others
│    │ 
│    ├─domain   领域层
│    │    ├─common           模块0-公共代码抽取,限于领域层有效  
│    │    ├─module-xxx       模块1-xxx,领域划分的模块,可理解为子域划分     
│    │    ├─module-user      模块2-用户子域(领域划分的模块,可理解为子域划分)
│    │    │    ├─action      行为定义
│    │    │    │    ├─UserDomainService.java        领域服务,用户领域服务
│    │    │    │    ├─UserPermissionChecker.java    其他行为,用户权限检查器
│    │    │    │    ├─WhenUserCreatedEventPublisher.java     领域事件,当用户创建完成时的事件 
│    │    │    ├─model       领域聚合内模型 
│    │    │    │    ├─UserEntity.java                领域实体,有唯一标识的充血模型,如本身的CRUD操作在此处
│    │    │    │    ├─UserDictVObj.java              领域值对象,用户字典kv定义       
│    │    │    |    ├─UserDPO.java                   领域负载对象    
│    │    │    ├─repostiory  领域仓储接口
│    │    │    │    ├─UserRepository.java
│    │    │    ├─reference   领域适配接口
│    │    │    │    ├─UserEmailSenderFacade.java
│    │    │    └─factory     领域工厂  
│    │ 
│    ├─infrastructure  基础设施层
│    │    ├─persistence      持久化机制
│    │    │    ├─converter   持久化模型转换器
│    │    │    ├─po          持久化对象定义 
│    │    │    └─repository.impl  仓储类,持久化接口&实现,可与ORM映射框架结合
│    │    ├─general          通用技术支持,向其他层输出通用服务
│    │    │    ├─config      配置类
│    │    │    ├─toolkit     工具类  
│    │    │    ├─extension   扩展定义  
│    │    │    └─common      基础公共模块等 
│    │    ├─reference        引用层,包装外部接口用,防止穿插到Domain层腐化领域模型等
│    │    │    ├─dto         传输模型定义
│    │    │    ├─converter   传输模型转换器       
│    │    │    └─facade.impl 适配器具体实现,此处的RPC、Http等调用
│    │ 
│    └─resources  
│        ├─statics  静态资源
│        ├─template 系统页面 
│        └─application.yml   全局配置文件

以上就是我对于两种工程结构的阐述,对于两种项目结构,大家要根据自己的项目情况和公司情况进行微调。原因是每种理论都有自己的产生背景、适用条件和使用方法,不能硬搬硬套。而且理论也是有很多变种的,例如ddd也有很多种架构的,例如:洋葱架构、六边形架构等,根据每项架构我们的工程结构肯定还会有一些变种,限于知识的理解不深,本次就不再描述了。ddd我了解的专家是张逸老师,他的著作《解构领域驱动设计》对于ddd的解释是比较全面的,我们做技术的也是基于在一个公司里面做业务,所以工作的上下文中又有了公司和业务者两块,针对这两块,现在的认识是要通过学习togaf这样的企业架构框架和周金根老师的《业务架构解构与实践》这样的著作来深化自己对做好技术工作的理解。

三、两种结构的适用背景

(一)阿里巴巴分层架构

现在对这个结构的认识是比较适用于:

1、在团队还比较小,职责还不是那么清晰的时候,

2、发展变化比较大的业务,因为此时还没有明确的领域概念,团队设置上也没有专人来保证领域的设计;

3、重心在与快速的支撑业务。

(二)ddd分层架构

DDD模式适用于以下几种场景:

1、支持处理复杂业务逻辑场景:当应用程序需要处理复杂的业务逻辑时,DDD可以将业务逻辑封装在领域模型中,从而更好地反映业务需求和业务流程,降低了系统架构的复杂度;

2、多团队协作:当多个团队共同开发一个大型系统时,DDD分层架构可以帮助团队之间更好地协作,每个团队负责不同的领域模型和业务逻辑,减少冲突和重复开发;

3、大型业务需要长期演化并快速迭代和交付的场景:每个子域都可以独立开发、部署和扩展,这样可以使得团队可以快速迭代和交付应用程序

如果将普通的CRUD业务系统也按照这套模式实现,反而会增加系统的复杂度。在现在的认识中,一般中大型的技术团队要能支撑起ddd这样的分层架构,在架构师层面至少有企业架构师、领域架构师(应用架构师)、业务架构师(应用架构师)、技术架构师、基础结构架构师,基础架构架构师有的有会分为、安全架构师、数据架构师其中的几个,但是在团队比较小变化大的业务中,很难支撑这样的团队配置,导致要在做好业务架构设计和时间、人力成本、机会成本、人员职责等产生了矛盾,最终妥协的结构应该就是采取阿里巴巴分层来快速低成本的支持业务跑起来。

参考:DDD-经典四层架构应用_ddd四层架构-CSDN博客、DDD领域驱动设计四、分层架构和代码模型_ddd四种领域模型-CSDN博客、Java应用工程结构 - CN.programmer.Luxh - 博客园 (cnblogs.com)、业务架构 - 知乎 (zhihu.com)、领域驱动设计 - 企业架构设计方法与实践 (tonydeng.github.io)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469273.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cordic算法圆周系统计算sin、cos、平方和开根、atan、坐标系变换

cordic算法圆周系统计算sin、cos、平方和开根、atan 一、cordic圆周系统旋转模式和向量模式1.1 旋转模式1.2 向量模式 二、一些需要考虑的事项2.1角度范围2.2输入正负2.3关于迭代精度2.4坐标系旋转 参考文献&#xff1a; 若想计算 s i n sin sin、 c o s cos cos、 x 2 y 2 \s…

CTFshow web(php文件上传155-158)

web155 老样子&#xff0c;还是那个后端检测。 知识点&#xff1a; auto_append_file 是 PHP 配置选项之一&#xff0c;在 PHP 脚本执行结束后自动追加执行指定的文件。 当 auto_append_file 配置被设置为一个文件路径时&#xff0c;PHP 将在执行完脚本文件的所有代码后&…

LeetCode Python - 16.最接近的三数之和

目录 题目答案运行结果 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 示例 1&#xff1a; 输入&#xff1a;nums [-1,2,1,-4],…

双链表简介

一.双链表 这里简单的介绍一下双链表&#xff0c;双链表也是和单链表是一种类型的结构&#xff0c;但是也有些许不同&#xff0c;其中不同的地方在于&#xff0c;双链表多了一个可以存储上一个单元的地址&#xff0c;并且是循环的链表&#xff0c;而且还增加了一个哨兵位&…

C语言—简单的if语句

1.输入你的身高和体重&#xff0c;测试你的健康状况。 计算bmi的值&#xff0c; bmi &#xff08;体重/身高的平方) 如果bmi 小于18.5&#xff0c;则显示“偏瘦&#xff0c;注意加强营养” 如果bmi 在18.…

网络原理(3)--以太网协议,DNS

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;网络原理(3)–以太网协议,DNS 在网络原理(2)中介绍了网络层中的一个重要的协议–ip协议,网络层关注的通信时的起点和终点,而数据链路层更加"底层"一些,关注的是传输过程…

如何在极低成本硬件上落地人工智能算法 —— 分布式AI

一、背景 分布式AI的发展前景非常广阔&#xff0c;随着5G、6G等高速网络通信技术的普及和边缘计算能力的提升&#xff0c;以及AI算法和硬件的不断优化进步&#xff0c;分布式AI将在多个领域展现出强大的应用潜力和市场价值&#xff1a; 1. **物联网&#xff08;IoT&#xff0…

Proteus -模拟串口被关闭后怎样打开

Proteus -模拟串口被关闭后怎样打开 点击恢复弹出窗口&#xff0c;即可重新打开

基于Echarts的可视化项目

整体的效果 概览区域 <!-- 概览区域模块制作 --><div class"panel overview"><div class"inner"><ul><li><h4>2190</h4><span><i class"icon-dot"></i>设备总数</span></…

软件实例分享,洗车店系统管理软件会员卡电子系统教程

软件实例分享&#xff0c;洗车店系统管理软件会员卡电子系统教程 一、前言 以下软件教程以 佳易王洗车店会员管理软件V16.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、会员卡号可以绑定车牌号或手机号 2、卡号也可以直接使用手机号&a…

121.乐理基础-五线谱-五线谱的临时变音记号规则

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;五线谱的多声部与指法问题 前置内容&#xff1a;还原号、临时变音记号在简谱中的规则 变音记号三个规则&#xff1a; 例子1&#xff1a;下方乐谱中午任意变音记号&#xff0c;所以就遵循第三个规则&#xff0c;它…

腾讯云4核8G服务器多少钱?

腾讯云4核8G服务器多少钱&#xff1f;轻量应用服务器4核8G12M带宽一年446元、646元15个月&#xff0c;云服务器CVM标准型S5实例4核8G配置价格15个月1437.3元&#xff0c;5年6490.44元&#xff0c;标准型SA2服务器1444.8元一年&#xff0c;在txy.wiki可以查询详细配置和精准报价…