如何结构化我们的代码

软件设计最佳实践,探讨按层、按特性和六边形架构/端口和适配器的代码结构。

在这篇文章中,我将探讨如何组织我们的代码并讨论最佳实践,涵盖三种不同的方法:按层、按特性和六边形架构/端口和适配器,以及它们的优缺点。

在探讨不同的代码结构方法之前,我们需要了解基本的软件设计原则:

内聚性(Cohesion) :指模块内部的类彼此相关的程度。•耦合性(Coupling) :指不同模块之间的依赖程度。

1*2Q8ye2K8hYRtNOMHWxoOBQ.png

模块性(Modularity) :指软件系统被分成独立模块的程度。每个模块封装了一组特定的功能,并被设计成能够独立工作,通过明确定义的接口与其他模块交互。•抽象化(Abstraction) :隐藏实现细节,只通过接口暴露必要的功能。•关注点分离(Separation of Concerns) :具有明确定义的各个部分,每个部分处理特定的关注点。•封装性(Encapsulation) :将数据和方法捆绑到单个模块或类中,以隐藏内部细节。

让我们更仔细地看看内聚性和耦合性?

内聚性描述软件的 关注点有多集中。它与单一职责原则密切相关。

高内聚性 意味着模块内的类彼此密切相关,并共享一个共同的、明确定义的目的。•低内聚性 意味着模块内的类关系不紧密,缺乏明确的目的,具有无关的责任。

遵循的最佳实践是追求高内聚性和松耦合

1*6DpCfIP-T09sZBfxu8G2DA.png

松散的耦合被认为是计算机系统良好结构和良好设计的迹象,与高内聚性结合使用时,可实现高可读性和可维护性。

1*WVS54T-5rqEvL7xf1AeADA.png

现在,让我们探讨不同的代码组织方式。首先,我将介绍按层组织,然后是按特性组织,对比这两者。之后,我们将探讨六边形架构/端口和适配器模式。

1*fmBZBkeP4RAmM9DwFoynyQ.png

按层组织

它表示一个项目结构,其中类被组织到多个层中,每个层负责一组特定的功能。

other 复制代码
src
├── main
│   ├── java
│   │   └── com
│   │       └── app
│   │           ├── service
│   │           │   └── UserService.java
│   │           │   └── OrderService.java
│   │           │   └── ProductService.java
│   │           ├── domain
│   │           │   └── User.java
│   │           │   └── Order.java
│   │           │   └── Product.java
│   │           ├── repository
│   │           │   └── UserRepository.java
│   │           │   └── OrderRepository.java
│   │           │   └── ProductRepository.java
│   │           ├── controller
│   │           │   └── UserController.java
│   │           │   └── OrderController.java
│   │           │   └── ProductController.java

典型的层包括:

1.表示层(Presentation Layer) :负责处理用户交互并向用户呈现信息。通常包括与用户界面、控制器和视图相关的组件。2.服务层(Service Layer) :包含业务逻辑并提供演示层所需的数据。3.领域包(Domain Package) :该包包含领域实体。4.数据访问层(Data Access Layer) :该层处理数据到/从数据库的持久化和检索。5.基础设施包(Infrastructure Package) :该包提供支持应用程序操作的服务。它可能包括用于日志记录、配置、安全等横切关注点的组件。

使用 按层组织 的一些缺点:

•低内聚性:不相关的类被组合到同一个包中。•高耦合性•封装性差:大多数类是公共的,因此我们无法将类设置为包私有,因为它们在其他层中是需要的。•低模块性:由于每个包包含与特定层相关的类,因此很难将代码分解为后来的微服务。•可维护性差:由于类散布在不同的包中,很难找到正在寻找的类。•它促进了数据库驱动设计,而不是领域驱动设计。

按特性组织

它表示一种根据功能或特性而不是层次结构组织代码的结构。在这种方法中,每个包代表一个独特且独立的功能。

目标是将与特定特性相关的所有组件(如控制器、服务、存储库和领域类)组合到一个包中。

other 复制代码
src
├── main
│   ├── java
│   │   └── com
│   │       └── app
│   │           ├── user
│   │           │   ├── UserController.java
│   │           │   ├── UserService.java
│   │           │   └── UserRepository.java
│   │           ├── order
│   │           │   ├── OrderController.java
│   │           │   ├── OrderService.java
│   │           │   └── OrderRepository.java
│   │           ├── product
│   │           │   ├── ProductController.java
│   │           │   ├── ProductService.java
│   │           │   └── ProductRepository.java

使用此结构的一些好处包括:

•高内聚性•低耦合性•强封装性:允许某些类将其访问修饰符设置为包私有而不是公共。•高模块性:由于每个包包含与特定功能相关的类,因此很容易将代码分解为后来的微服务。•可维护性:减少了在包之间导航的需求,因为所有与特性相关的类都在同一个包中。•促进了领域驱动设计

六边形架构/端口和适配器模式

六边形架构,也称为端口和适配器,是由阿利斯泰尔·科克本博士在他2005年的一篇文章中介绍的软件架构模式。[1]

该模式通过保持核心业务逻辑独立于外部细节,并不紧密耦合于数据库、用户界面或外部服务等外部依赖,促进了关注点的隔离/分离。

这使得测试、维护和发展系统更加容易。

1*wF_VJcN5dpwCQB_sx1z2_w.png

在此模式中:

1.领域/核心(Domain / Core) 代表应用程序的业务逻辑或领域(应用程序的核心)。2.端口(Ports) 端口是核心定义的接口,允许与外部组件进行交互。这些可以包括服务、存储库或任何外部依赖的接口。3.适配器(Adapters) 适配器是端口的实现。它们将核心应用程序连接到数据库、用户界面和外部服务等外部组件。适配器可以针对不同的技术或协议进行特定的实现。4.主要操作者(Primary actors) 系统的使用者,如webhook、UI请求或测试脚本。5.次要操作者(Secondary actors) 被应用程序使用的这些服务是 Repository(例如数据库)或 Recipient(例如消息队列)。

1*AUdml5HCo92xf8WgHkZfRA.gif

六边形形状:

六边形形状象征着核心应用程序位于中心,周围是适配器。这个形状代表了核心与其外部依赖之间的明确分离。

顶级包结构应如下所示:

other 复制代码
src/main/
  java
    mina
      dev
        <servicename>
          adapters
          config
          core
          <ServiceApplication>.java

根包应只包含包:coreadaptersconfig

core 包含服务的所有领域逻辑。它可以包含子包。•端口应该位于 core 包中:端口只是由核心声明的要调用或由适配器实现的接口。•adapters 包含所有适配器实现代码。它可以包含子包以按单个适配器或技术组织适配器代码。•config 包含用于连接不同组件的配置类。

包依赖规则:

•根包可以依赖于所有其他包。•config 包可以依赖于 coreadapters。•adapters 可以依赖于 core,但不可以依赖于 config。•core 不得依赖于其他任何包。

希望这篇文章能够帮助您更好地理解不同的代码结构。

引用链接

[1] 软件架构模式。: alistair.cockburn.us/hexagonal-a...

相关推荐
艾迪的技术之路18 分钟前
redisson使用lock导致死锁问题
java·后端·面试
今天背单词了吗98036 分钟前
算法学习笔记:8.Bellman-Ford 算法——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·开发语言·后端·算法·最短路径问题
天天摸鱼的java工程师39 分钟前
使用 Spring Boot 整合高德地图实现路线规划功能
java·后端
东阳马生架构1 小时前
订单初版—2.生单链路中的技术问题说明文档
java
咖啡啡不加糖1 小时前
暴力破解漏洞与命令执行漏洞
java·后端·web安全
风象南1 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端
DKPT1 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
Percep_gan2 小时前
idea的使用小技巧,个人向
java·ide·intellij-idea
缘来是庄2 小时前
设计模式之迭代器模式
java·设计模式·迭代器模式