你的 LLMs 并不做真正的 OOP,而且它是结构性的。

发布: (2026年2月18日 GMT+8 18:35)
7 分钟阅读
原文: Dev.to

Source: Dev.to

请提供您希望翻译的完整文本(除代码块、URL 和源链接外),我将把它翻译成简体中文并保持原有的 Markdown 格式。

生成式 AI 每天都在写代码

类、服务、模型、控制器。乍一看,一切都很正常。它可以编译,能够通过测试,并且“完成任务”。

然而,却存在一个反复出现的问题:

LLM 生成的代码通常封装性差。
不是“有点差”。
结构上封装性差。

类里充斥着 getter 和 setter,几乎没有行为,业务逻辑散落各处。简而言之:面向数据的代码,而非面向对象的代码。

为什么会这样?
更重要的是:使用 AI 时如何做得更好?

Source:

OOP 最初的含义(以及我们忘记的)

当我们今天谈论面向对象编程时,常常想到:

  • 私有属性
  • getter / setter
  • 接口

但这 不是 最初的愿景。

Alan Kay(被视为 OOP 之父之一)而言,核心思想不是类,而是 消息

“对我而言,面向对象仅意味着消息传递、本地保留与保护以及隐藏状态过程,并且对所有事物进行极端的后期绑定。”

换句话说:

  • 对象 相互通信
  • 它们 自行保留状态
  • 它们 隐藏内部逻辑
  • 它们 松耦合

他使用的类比是生物学的:自主的细胞在不暴露内部器官的情况下相互作用。

LLM 生成的内容

Typical example generated by an AI:

public class User {
    private String email;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

它很简洁。根据许多教程,它是“最佳实践”。但它不是封装。

为什么?

  • 内部状态被暴露
  • 内部类型被固定
  • 缺少验证
  • 业务逻辑被推到外部

结果:行为最终出现在服务、控制器中,甚至更糟……在各处被复制。我们称之为贫血类:一个只有访问器的简单数据袋。

Getter / Setter 的虚假安全感

Getter 和 setter 给人封装的幻象,但实际上:

  • 它们暴露内部结构
  • 它们导致强耦合
  • 它们冻结实现决策

更改字段、其类型或其逻辑会迅速导致广泛的破坏。在面向对象编程中,暴露状态几乎总是抽象泄漏

对对象提出更好的问题

而不是这样问:

if (user.getEmail() == null) {
    // logic here
}

而是这样问:

if (user.canBeContacted()) {
    // logic here
}

这已经是进步了:

  • 行为已本地化
  • 业务规则位于对象中
  • 实现可以演进

但我们可以走得更远。

消息与事件方法

在 Alan Kay 的设想中,对象并不说明 它是什么;它响应 被请求的内容

而不是读取状态:

  • 你发送一个意图
  • 对象自行决定
  • 状态保持内部

事件驱动或面向消息的模型正好实现了这一点:

  • 内部状态转换
  • 强解耦
  • 逻辑集中于一处

这并不是“更复杂”。而是 更明确

为什么大型语言模型在真正的封装上如此挣扎

这并不是因为 AI “不好”。而是结构性原因。

  • 它们从现有代码中学习 —— GitHub 上充斥着 CRUD、DTO、贫血类。
  • Getter / Setter 在统计上占主导,因此它们“可能”出现并被生成。
  • 业务行为具有上下文性;LLM 在局部表现出色,但在全局一致性方面较弱。
  • 面向消息的代码更简洁但更抽象,缺乏明确意图时更难推断。

AI 并不了解你的领域。它只是外推模式。

如何更好地使用 AI 编写面向对象代码

解决方案不是停止使用 AI。解决方案是 更好地引导它

当你生成一个类时,问问自己(也问模型)以下问题:

  • 这个类是 在做某事,还是仅仅用于传输数据?
  • 我是 向对象提问,还是 读取它的状态
  • 行为是 局部化 还是分散的?
  • 我能在不破坏调用方的情况下更改实现吗?

如果答案是 “no”,那么它可能并不是真正的面向对象。

真正的问题不在于 AI

问题在于:

  • 我们已经把贫血的面向对象(OOP)标准化了
  • 我们把封装和可见性混淆了
  • 我们用数据结构取代了行为

大型语言模型仅仅 复制了我们多年来所产生的内容

结论

封装不是:

  • 私有字段
  • 公共 getter
  • 被动模型

封装是:

  • 对其状态负责的对象
  • 本地化业务规则
  • 使用消息而非直接访问
  • 最小耦合

AI 可以帮助,但 它永远无法取代良好的建模

进一步阅读

阅读 Dave 的博客上的 “Loopy Loops”

0 浏览
Back to Blog

相关文章

阅读更多 »

Python 中的实例变量和实例方法

Python 中的实例变量与实例方法 在面向对象编程(Object‑Oriented Programming,OOP)中,你必须掌握的两个概念是: - 实例变量 - 实例方法

Overton 框架现已获得 DOI 背书

概述:Overton Framework Protective Computing 现已在 Zenodo 上归档,并获得了 DOI,提供了一个稳定的、带版本的引用,供论文、文档等使用。

OpenClaw 设计上不安全

OpenClaw 设计上不安全 Cline 供应链攻击 2月17日 一个流行的 VS Code 扩展 Cline 被攻破。攻击链展示了多个 AI …