JetBrains AI 打零工(四)——维护 Junie Guidelines 与代码可追溯

这里介绍两个实践 Junie 基本原则,有助于提升工程效率。第一个是设置编码规约,也就是 Junie Guidelines,另一个是 IDEA 的代码追溯功能,也就是 Local History,并结合 Git 使用。前者约束 Junie 代码生成的基本规范,后者查找代码修改记录。

一、Junie Onboarding

Junie Guidelines 指的是一份作用于项目全局的规则,用于约束 Junie 生成的代码。有了这样一份约束,就不需要在每次调用代理时重复声明,这已然成为了 AI IDE 达成共识的产品设计,比如 Cursor Rules。

这份文档包含个人或团队的编码规约:

  • 建议使用的最佳实践
  • 应当避免的反模式
  • 编码风格、命名约定
  • 代码示例

1、生成 guidelines.md

Junie 约定使用 .junie/guildelines.md 作为 Junie Guidelines。

如果没有该文件,可基于项目背景生成一个,提示词如下:

Analyze the project structure and tech stack, and create a .junie/guidelines.md file with concise, well-structured information to help new developers. Include guidance on organizing the structure, running tests, executing scripts, and following best practices. Keep the content short, clear, and practical.
分析项目结构和技术栈,并创建一个.junie/guidelines.md 文件。文件中包含如何组织结构、运行测试、执行脚本以及遵循最佳实践的指导。内容简洁、清晰、实用,可以有效帮助新开发者。

Junie 会在后台花费几分钟时间不断通过 「ls」命令发现文件并检查结果,这份基础文件有了第一个版本后就可以不断迭代,代码生成采纳率也会有所提升,也不需要每次对话都重复强调代码规范。

这与 README 不同的是,README 用于介绍项目背景与关键技术,用于新人快速了解项目,而 Guidelines 则用于约束 Junie 生成代码的规则,是一份具体的编程规约,比如项目结构、命名规范、技术选型与标准、架构约束等。

2、不断迭代 Guidelines

这里推荐 JetBrains 开源的一份 Junie Guidelines。这些看似约定俗成的编码规约却可以在团队协作中发挥巨大作用,减少新成员加入、项目周期压缩对项目质量的快速破坏,并建立团队默契,减少认知分歧。

下面举例介绍几个:

(1)优先使用构造函数注入而非字段/Setter 注入

  • 将所有必需的依赖声明为 final 字段,并通过构造函数注入
  • 如果只有一个构造函数,Spring 会自动检测,无需在构造函数上添加 @Autowired 注解
  • 避免在生产代码中使用字段或 setter 注入

解释:

  • 通过将所有必需依赖作为 final 字段并通过构造函数注入,可以保证对象始终处于正确初始化的状态,仅依赖于 Java 语言特性,无需额外依赖
  • 这样可以在不依赖反射初始化或 Mock 的情况下编写单元测试
  • 构造函数注入清晰地传达了类的依赖关系,无需深入源代码即可了解
  • Spring Boot 提供了如 RestClient.BuilderChatClient.Builder 等扩展点,通过构造函数注入可以进行自定义并初始化实际依赖
java 复制代码
@Service
public class OrderService {
   private final OrderRepository orderRepository;
   private final RestClient restClient;

   public OrderService(OrderRepository orderRepository, 
                       RestClient.Builder builder) {
       this.orderRepository = orderRepository;
       this.restClient = builder
               .baseUrl("http://catalog-service.com")
               .requestInterceptor(new ClientCredentialTokenInterceptor())
               .build();
   }

   //... 方法
}

(2)分离 Web 层与 ORM 层

  • 不要在控制器中直接暴露实体作为响应
  • 明确定义请求和响应记录(DTO)类
  • 在请求记录类上应用 Jakarta 校验注解以强制输入规则

解释:

  • 直接返回或绑定实体会将公共 API 与数据库结构紧耦合,未来更改风险较大
  • DTO 可以清晰声明客户端可发送和接收的字段,提升清晰度和安全性
  • 每个用例专用的 DTO 可以直接注解字段进行校验,无需复杂的校验分组
  • 建议使用 Java bean 映射库简化 DTO 转换,优先选择能在编译期生成映射实现的 MapStruct,避免运行时反射开销

(3)遵循 REST API 设计原则

  • 版本化、面向资源的 URL: 端点结构应为 /api/v{version}/resources(如 /api/v1/orders
  • 集合与子资源保持一致的 URL 模式: 例如 /posts 表示帖子集合,/posts/{slug}/comments 表示指定帖子的评论
  • 通过 ResponseEntity 明确 HTTP 状态码: 使用 ResponseEntity<T> 返回正确的状态码(如 200 OK、201 Created、404 Not Found)及响应体
  • 对可能包含大量数据的集合资源使用分页
  • JSON 数据必须以对象为顶层结构,便于未来扩展
  • JSON 属性名统一使用小驼峰 camelCase 命名

解释:

  • 可预测性和易发现性: 遵循 REST 规范让 API 更直观,客户端无需大量文档即可猜测 URL 和行为
  • 可靠的客户端集成: 标准化的 URL、状态码和头部信息,便于消费者稳定对接 API,了解每个响应的结构和意义
  • 更多 REST API 设计规范请参考 Zalando RESTful API and Event Guidelines

(4)集中异常处理

  • 定义全局处理类,使用 @ControllerAdvice(或 REST API 场景下的 @RestControllerAdvice)和 @ExceptionHandler 方法处理特定异常
  • 返回一致的错误响应,建议采用 ProblemDetails 响应格式(RFC 9457

解释:

  • 应始终处理所有可能的异常,并返回标准错误响应,而不是直接抛出异常
  • 建议使用 GlobalExceptionHandler 集中管理异常处理逻辑,而不是在控制器中重复 try/catch

二、代码可追溯

1、Code Review

这是大模型在编程领域发展成熟度与软件工程客观规律所共同作用的,即使一些顶尖大模型可以达到生产可用的代码质量,但是程序员依然需要监督代码生成结果。

尤其对于 Java 更是如此,不仅要对 Junie 生成的结果负责也要理解它的代码编写逻辑。在没有足够的测试网覆盖下,生成代码仍然需要人为验证结果准确性,因为 Junie 自己的测试计划可能会绕过实际的结果,也就是看似通过了它的测试,实际上这些测试并没有达到验证我们提出的任务要求。

然后再对代码结构做审查,起码能看懂 Junie 的代码逻辑,因为可读性决定可维护性,Junie 不能也暂不具备能力为所有 issue 负责,程序员依然是代码的最终负责人。

那么,功能性质量与非功能性质量都要做的情况下,Junie 只不过是加快了部分效率而已。

2、Git Commit 与 Local History

Junie 并行执行多个任务,同时修改大量文件的结果是程序员没法同时跟踪所有代码修改结果。好比多个 Coding Agent 构成的虚拟开发团队,做到提交互不冲突,就需要 Git 这样的版本控制工具彰显威力了,保证每次代码修改可控。同样需要保证,交给 Junie 的任务是否正交分解,够小够清晰,这就是任务分解能力了。

可是,Git Commit 在 Junie 面前可能还是会有些重,因为存在需求变动、实现不达标的情况导致一段代码反复修改,甚至 commit history 都无法分清到底做了发生了什么。这时候可以借助 Local History 来辅助,对于手动修改还是 Junie 修改记录都一目了然。

代码修改力度足够小,Junie 在一个任务的中间过程都会被记录下来。

触发方式是:两次 Shift 输入 Local History。

相关推荐
90后的晨仔5 分钟前
使用Trae这个AI工具实现一个个性的技术博客
ai编程
MrSkye3 小时前
从零到一:我用AI对话写出了人生第一个弹幕游戏 | Prompt编程实战心得
前端·ai编程·trae
用户18881478528814 小时前
谷歌Gemini编程吊打全场,国产AI全歇菜。
ai编程
俞乾4 小时前
这三个 MCP 组合,让 Cursor 指哪打哪
ai编程·cursor·vibecoding
沐森5 小时前
langchain相关介绍
langchain·ai编程
量子位6 小时前
Scaling Law 首次在自动驾驶赛道被验证!小鹏汽车 CVPR 演讲详解:AI「吃」下 6 亿秒视频后,智能涌现
chatgpt·ai编程
量子位6 小时前
全方位实测首个 AI 原生浏览器!618 比价、写高考作文... 网友:再见 Chrome
人工智能·ai编程
加16 小时前
95%代码AI生成,是的你没听错...…
前端·ai编程
我姚学AI8 小时前
大厂程序员自研Flomo AI插件,1秒总结笔记,官方都没做到!
ai编程