欢迎光临
我们一直在努力

优美的代码是艺术

        正确的代码是科学,可靠的代码是工程,优美的代码是艺术。

引子:一段“能跑就行”的代码,三个月后成了团队的噩梦

这种场景在软件开发团队里反复出现:前任开发者交付时很自豪:“全部测试通过,功能完整,性能达标。”

但当我们打开代码时,所有人都沉默了:

def parse_prd(data):

    第一版实现,别乱改

    if data:

        if type(data) == str:

            if len(data) > 0:

                各种处理逻辑

                for x in data.split('\\n'):

                    if '用户故事' in x:

                        这里以前有bug,后来修了,具体忘了怎么修的

                        tmp = x.split(':')[1].strip()

                        再处理一下

                        # …(此处省略200行)

三个月后,产品经理提出新需求:“支持从Excel导入PRD。”

我们评估的结论是:与其改这段代码,不如重写。

这不是个例。在AI辅助编程时代,代码生成速度提高了10倍,但代码的丑陋程度也同步提高了10倍。AI擅长“写出来”,但不擅长“写得好看”。而“好看”这件事,恰恰决定了软件能活多久。

这引出了软件质量的第三个维度——优美性。

一、优美性的三层内涵:结构、味道、可读

在我们团队的定义中,软件的优美性不是“好看”这种主观感受,而是三个可量化的工程维度:

1. 结构合理:用设计模式构建“抗变化”的骨架

优美代码的第一层,是架构层面的稳定性。

好的结构不是“今天能跑”,而是“未来能改”。它能够在需求变化时,只改动局部,而不牵一发动全身。

变化类型

无结构设计(硬编码)

有结构设计(设计模式)

新增一种PRD格式

修改主解析函数,新增if-else分支

新增一个Parser实现,无需改动现有代码

更换LLM供应商

全局搜索替换API调用

通过Adapter模式隔离,只换一个类

支持新的输出格式

修改所有输出点

新增一个Formatter,符合开闭原则

设计模式的本质不是“套用模板”,而是“找到稳定的抽象点,封装变化点”。

2. 没有坏味道:让代码“呼吸顺畅”

代码坏味道(Code Smell)不是Bug——Bug是“代码做错了”,坏味道是“代码虽然现在没错,但未来一定会变成麻烦”。

我们在代码审查中重点关注的坏味道清单:

坏味道

表现

典型示例

重复代码

相同逻辑出现≥3次

同一个解析逻辑在3个不同函数中出现

长函数

超过50行,做了多件事

一个函数既解析又校验又存储还发通知

过深的嵌套

if/for嵌套≥3层

if a: for b: if c: for d: …

临时变量过多

一个函数中超过5个临时变量

tmp1, tmp2, temp_data, result_temp, final_xxx

散弹式修改

改一个需求需要改5个文件

新增一个字段要改实体、DAO、Service、DTO、API

过度的防御

所有地方都判空,掩盖设计问题

明明不可能为null的地方也加了if,还写了降级

3. 可读性强:代码是写给人看的,顺便让机器执行

优美的代码,应该像一篇清晰的散文——变量名自解释,结构有层次,注释不冗余。

命名对照表:

❌ 糟糕的命名

✅ 优美的命名

说明

data

prd_content

具体是什么数据?

process()

parse_markdown_to_stories()

处理什么、输出什么?

flag

is_valid_format

布尔值以is/has开头

tmp

raw_section

临时变量也有意义

do_stuff()

extract_acceptance_criteria()

在做什么事?

二、优美性与正确性、可靠性的关系

三个维度不是并列的,而是层层递进、互相支撑的:

维度

核心问题

失败后果

正确性

“做对了吗?”

功能错,用户投诉

可靠性

“在意外下还能对吗?”

系统崩,线上事故

优美性

“下次改的时候还能对吗?”

改不动,技术债务堆积

优美性是正确性和可靠性的“时间放大器”:

  • 没有优美性,正确性会在第一次需求变更时就崩塌;
  • 没有优美性,可靠性会在第一次重构时就被破坏;
  • 优美性让正确性可以持续,让可靠性可以进化。

用一个比喻来理解三者的关系:

三、如何让AI写出优美的代码?四个可落地策略

AI默认生成的是“能跑”的代码,不是“好看”的代码。要让AI产出优美代码,需要在Prompt和流程中显式约束。

策略1:强制设计模式选择

在需求分析阶段,强制AI先输出设计决策,再输出代码:

## 设计决策(必须输出)

– 当前场景中,哪些是"稳定的抽象点"

– 未来最可能变化的方面是什么?

– 选择什么设计模式来隔离变化?

示例:

"当前支持Markdown解析,未来可能支持Excel/Word,因此采用策略模式(Strategy Pattern),Parser接口作为抽象,各格式解析器作为具体实现。"

策略2:代码审查的坏味道检查清单

在AI交付代码前,自检以下清单(我们在System Prompt中强制要求):

□ 是否有重复代码块(相同逻辑出现≥2次)?

□ 是否有函数超过30行?

□ 是否有嵌套超过3层(if/for/while)?

□ 是否有超过3个临时变量(tmp1, tmp2, result_temp…)?

□ 是否有硬编码常量(如"https://api.xxx.com"直接写在代码里)?

□ 是否有类或模块承担了多个职责?

□ 所有函数名是否以动词开头,并能从命名推断其行为?

□ 所有布尔变量是否以is/has/should开头?

□ 注释是否解释"为什么"而非"是什么"

策略3:重构优先于扩展

给AI的指令中嵌入一条原则:

"当实现新需求时,优先考虑能否通过修改现有结构来满足,而非新增逻辑。如果发现新增逻辑需要打补丁式修改,请先重构现有代码使其结构支持新需求,再实现功能。"

这个原则防止了代码走向“补丁摞补丁”的死亡螺旋。

策略4:可读性量化门禁

在交付前,AI必须输出以下可读性指标:

指标

目标值

检查方法

函数平均行数

≤30行

静态分析

嵌套深度

≤3层

静态分析

命名规范符合率

100%

正则匹配 + 语义检查

注释密度

关键决策点必有注释

AI自检

重复代码率

≤5%

代码克隆检测工具

四、一个实战案例:两个版本的需求工程Agent

版本1:能跑就行(无优美性设计)

def parse_prd(data):

    开始解析

    lines = data.split('\\n')

    stories = []

    for i in range(len(lines)):

        if '用户故事' in lines[i]:

            找到故事

            story = lines[i].split(':')[1]

            找验收条件

            j = i + 1

            while j < len(lines):

                if '验收条件' in lines[j]:

                    找到了

                    condition = lines[j].split(':')[1]

                    stories.append({'story': story, 'condition': condition})

                    break

                j += 1

    这里可能有bug,但先这样吧

    return stories

问题:长函数、深嵌套、硬编码、无结构、命名模糊、注释无效。

版本2:优美设计

from abc import ABC, abstractmethod

class PRDParser(ABC):

    """PRD解析器接口 – 策略模式"""

    

    @abstractmethod

    def parse(selfcontentstr) -> List[UserStory]:

        """解析PRD内容,返回用户故事列表"""

        pass

class MarkdownPRDParser(PRDParser):

    """Markdown格式PRD解析器"""

    

    def __init__(selfsection_markerstr = "用户故事"):

        self.section_marker = section_marker

    

    def parse(selfcontentstr) -> List[UserStory]:

        sections = self._split_by_marker(content, self.section_marker)

        return [self._parse_section(s) for s in sections]

    

    def _split_by_marker(selfcontentstrmarkerstr) -> List[str]:

        """按标记切分文档段落"""

        具体实现

    

    def _parse_section(selfsectionstr) -> UserStory:

        """解析单个段落为用户故事"""

        具体实现

class ExcelPRDParser(PRDParser):

    """Excel格式PRD解析器 – 扩展时新增,无需改现有代码"""

    

    def parse(selfcontentstr) -> List[UserStory]:

        # Excel解析实现

        pass

class PRDParserFactory:

    """工厂模式 – 根据文件类型创建对应的解析器"""

    

    @staticmethod

    def create(file_typestr) -> PRDParser:

        parsers = {

            "markdown": MarkdownPRDParser,

            "excel": ExcelPRDParser,

            "word": WordPRDParser,

        }

        return parsers.get(file_type, MarkdownPRDParser)()

优势:

  • 每个函数≤30行,单一职责
  • 策略模式支持新格式扩展,无需修改现有代码
  • 命名自解释(parse、_split_by_marker)
  • 注释解释“为什么用策略模式”而非“代码在做什么”

五、优美性的长期价值:代码是资产,不是负债

很多团队认为“优美性是锦上添花,有空再做”。但数据告诉我们不同的故事:

阶段

无优美性的代码

有优美性的代码

第1个月交付速度

⚡ 快

⚡ 较快(多花20%时间设计)

第3个月新增需求

�� 半天

�� 1小时

第6个月新人上手

�� 2周

�� 2天

第12个月技术债务

�� 需要重写

�� 持续可维护

第24个月总成本

❌ 远高于重写

✅ 持续降低

优美的代码不是奢侈品,而是降低总拥有成本(TCO)的最有效手段。

六、我们给Agent的优美性指令(可直接复用)

在AI编程助手的System Prompt中,我们嵌入了这样一段指令:

“在交付代码之前,请完成以下三件事:

  • 结构审视:识别当前场景中未来最可能变化的3个方面,说明你用何种设计模式/结构来隔离这些变化,并对每个变化点给出具体的扩展示例。
  • 味道自查:对照坏味道清单(重复代码、长函数、深嵌套、临时变量过多),逐项检查你的代码。如有发现,立即重构后再交付。
  • 可读性验证:假设一位新同事在半年后第一次阅读这段代码,他能否在5分钟内理解代码的意图和结构?如果他需要超过5分钟,请补充注释、拆分函数、优化命名。
  • 最终交付标准:代码应像一篇清晰的散文,而不是一份潦草的草稿。”

    七、结语:优美性是软件生命力的保障

    回到我们最初的比喻:

    • 正确性决定了软件能不能用——这是下限
    • 可靠性决定了软件敢不敢用——这是信任线
    • 优美性决定了软件能活多久——这是生命力线

    在AI辅助编程的时代,代码生成的速度不再是瓶颈。瓶颈变成了:我们能否让AI生成的代码,像人类中的优秀工程师写的一样清晰、优雅、可维护。

    这不是审美偏好,而是工程生存问题。优美性差的代码,终将被技术债务吞噬;优美性好的代码,会成为团队最可靠的长期资产。

    赞(0)
    未经允许不得转载:171主机测评 » 优美的代码是艺术
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址