Java功能结构案例怎么规整

wen java案例 31

本文目录导读:

Java功能结构案例怎么规整

  1. 核心原则
  2. 标准项目结构(包结构)
  3. 具体代码层级规整(以“创建用户”为例)
  4. 规整清单(Checklist)
  5. 规整后的优点

针对 Java 功能结构案例的规整,核心在于遵循清晰的分层架构(通常是 MVC 或其变体)和统一的命名规范,案例代码应具备可读性可测试性可扩展性

以下是规整 Java 功能结构案例的标准化步骤和具体示例。

核心原则

  1. 按功能(业务领域)分包,而非按层分包:这是与早期项目最大的区别,将相关的 Controller、Service、DAO、DTO 放在同一个包下。
  2. 单一职责:一个类、一个方法只做一件事。
  3. 依赖倒置:依赖抽象(接口),而非具体实现。
  4. 清晰的层次划分:严格区分 Request/Response(应用层)、Service(业务层)、Repository(数据层)。

标准项目结构(包结构)

假设一个“用户管理”模块:

src/main/java/com/example/demo/
│
├── config/                  # 配置类(全局,非功能模块)
│   └── WebMvcConfig.java
│
├── common/                  # 通用工具、异常、常量(全局)
│   ├── exception/
│   │   ├── GlobalExceptionHandler.java
│   │   └── BusinessException.java
│   ├── result/
│   │   └── Result.java      # 统一响应体
│   └── util/
│       └── StringUtils.java
│
├── modules/                 # 功能模块(核心)
│   ├── user/                # 🎯 用户模块
│   │   ├── controller/      # 1. 控制层
│   │   │   └── UserController.java
│   │   ├── service/         # 2. 服务层
│   │   │   ├── UserService.java          (接口)
│   │   │   └── impl/
│   │   │       └── UserServiceImpl.java  (实现)
│   │   ├── repository/      # 3. 数据访问层
│   │   │   └── UserRepository.java
│   │   ├── entity/          # 4. 数据实体(与DB对应)
│   │   │   └── User.java
│   │   ├── dto/             # 5. 数据传输对象(专门给API用)
│   │   │   ├── request/
│   │   │   │   └── UserCreateRequest.java
│   │   │   └── response/
│   │   │       └── UserResponse.java
│   │   └── converter/       # 6. 对象转换器(可选,可用MapStruct代替)
│   │       └── UserConverter.java
│   │
│   └── order/               # 另一个功能模块
│       ├── controller/
│       └── ...
│
└── Application.java         # 启动类

为什么这样规整?

  • 高内聚:用户的所有代码都在 user 包内,修改用户功能只需关注这一个目录。
  • 低耦合user 模块不直接依赖 order 模块的具体类,只依赖其接口或 DTO。
  • 易于维护:新同事接手时,能快速定位业务逻辑。

具体代码层级规整(以“创建用户”为例)

Controller 层(控制层):只负责接收参数和返回结果

@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping
    public Result<UserResponse> createUser(@RequestBody @Valid UserCreateRequest request) {
        // 1. 调用业务层
        UserResponse response = userService.createUser(request);
        // 2. 返回统一格式
        return Result.success(response);
    }
}

Request/Response(请求/响应):完全独立,不包含业务逻辑

// UserCreateRequest.java (入参校验)
@Data
public class UserCreateRequest {
    @NotBlank(message = "用户名不能为空")
    @Size(min = 4, max = 20, message = "用户名长度需在4-20字符之间")
    private String username;
    @Email(message = "邮箱格式不正确")
    private String email;
    private String phone;
}
// UserResponse.java (出参,不暴露敏感字段)
@Data
public class UserResponse {
    private Long id;
    private String username;
    private String email;
    private String phone;
    private LocalDateTime createdAt;
}

Service 层(业务层):核心业务逻辑,使用接口 + 实现类

// UserService.java (接口)
public interface UserService {
    UserResponse createUser(UserCreateRequest request);
}
// UserServiceImpl.java (实现)
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserConverter userConverter; // 对象转换器
    @Override
    public UserResponse createUser(UserCreateRequest request) {
        // 1. 业务校验(如检查用户名是否已存在)
        if (userRepository.existsByUsername(request.getUsername())) {
            throw new BusinessException(400, "用户名已存在");
        }
        // 2. 转换 Request -> Entity
        User user = userConverter.toEntity(request);
        // 3. 调用数据层保存
        User savedUser = userRepository.save(user);
        // 4. 转换 Entity -> Response
        return userConverter.toResponse(savedUser);
    }
}

Repository 层(数据访问层):只包含数据库操作,使用 Spring Data JPA/MyBatis-Plus

// UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    boolean existsByUsername(String username);
}

Entity 实体层:与数据库表字段一一对应,使用 JPA 注解

// User.java
@Entity
@Table(name = "sys_user")
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(nullable = false, unique = true)
    private String username;
    private String email;
    private String phone;
    @Column(updatable = false)
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    @PrePersist
    protected void onCreate() {
        this.createdAt = LocalDateTime.now();
        this.updatedAt = LocalDateTime.now();
    }
}

Converter(对象转换器):避免手动写 get/set,推荐使用 MapStruct

// UserConverter.java (MapStruct)
@Mapper(componentModel = "spring")
public interface UserConverter {
    User toEntity(UserCreateRequest request);
    UserResponse toResponse(User user);
}

规整清单(Checklist)

在提交代码前,请逐一检查:

类别 要求 示例
命名规则 类名使用 PascalCase,变量/方法使用 camelCase UserCreateRequest, getUserName()
分层清晰 Controller 不能注入 Repository 必须通过 Service 层
异常处理 全局异常处理,业务异常定义标准码 throw new BusinessException(400, "xxx")
参数校验 使用 @Valid + @NotBlank 写在 Request 类上
无用依赖 禁止在 Controller 中引入 Entity 用 DTO 替代
日志规范 使用 SLF4J 接口,打印关键入参和异常 log.info("创建用户:{}", request)
单元测试 核心 Service 方法应有测试 JUnit + Mockito

规整后的优点

  1. 可读性强:打开 modules/user 目录,就能看清该模块的完整骨架。
  2. 易于测试:Service 层的接口和实现分离,便于使用 Mock 进行单元测试。
  3. 易于协作:多人开发时,每人负责一个 modules/xxx 模块,减少代码冲突。
  4. 易于重构:要修改用户查询逻辑,只需修改 UserServiceImplUserRepository,不影响其他模块。

通过这种规整方式,Java 功能结构案例会变得逻辑清晰、代码整洁,非常适合用于团队协作或教学演示。

抱歉,评论功能暂时关闭!