news 2026/5/9 18:12:40

别人写的代码看不懂,到底是谁的水平有问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别人写的代码看不懂,到底是谁的水平有问题

你突然看到某段代码用了工厂模式,第一反应可能是:有必要吗?直接new一个对象不行吗?干嘛「故意」增加阅读难度?

其实不是这样的,当你接触过的高手多了后,你会自然而然的认为:高手的代码,确实不太容易看懂,尤其你水平还不够的时候。

我不是说你菜,只是每个人都会经历过这个阶段的。关键在于,你得分清楚一件事:到底是代码本身写得烂,还是你的知识面暂时还覆盖不到这里。

你觉得没必要,可能是你还没遇到那个场景

如果你构造的对象只是简单地设置几个属性,确实没必要用工厂。直接用构造方法或者Builder就够了。

问题出在另一种场景:构造一个业务对象的过程本身就很复杂。

拿门店进销存系统中的物料盘点模块举例。创建一张盘点单据,需要做这些事情:

  • 根据模板ID去查盘点模板,拿到模板里配置的名称、类型、盘点日期规则
  • 调用编码生成服务,按照业务规则生成单据编号
  • 把提交过来的物料数据逐条转换成明细实体
  • 把以上所有数据组装成一个完整的聚合根对象

这不是简单地new一个对象然后set几个字段。整个构造过程涉及到外部服务调用、数据库查询、业务规则计算。如果这些逻辑散落在调用方的代码里,那每个需要创建盘点单据的地方都得重复写一遍。

用工厂模式封装这些构造逻辑,代码大概长这样:

@ComponentpublicclassStocktakingDocsFactory{privatefinalCodeGeneratorServicecodeGeneratorService;privatefinalStocktakingTemplateRepositorytemplateRepository;publicStocktakingDocsAggregateRootcreate(SubmitStocktakingCommandcommand){// 查询模板,获取名称、类型、日期规则StocktakingTemplatetemplate=templateRepository.getById(command.getTemplateId());// 生成单据编号Stringcode=codeGeneratorService.generate(ModuleEnum.STOCKTAKING);// 组装明细List<StocktakingItemEntity>items=buildItems(command.getMaterialList());// 构建聚合根returnStocktakingDocsAggregateRoot.builder().code(code).name(template.getName()).type(template.getType()).items(items).build();}}

调用方只需要一行factory.create(command)就拿到了完整的聚合根对象。构造过程中涉及到的模板查询、编码生成、数据转换这些细节,全部被封装在工厂内部。

当你知道工厂模式就是干这个事情的时候,看到对应的代码会觉得很自然。觉得绕,往往是因为你还没遇到过需要它的场景。

高手的代码都是精心组织过的

我带过的团队里,水平高的那几个人,写出来的代码有一个共性:都是有规划、有设计的。随意写代码,对他们来说是大忌。

你甚至会经常听到他们说这句话:不要这搞一个,那搞一个,要设计和规划的。

这基本是他们的口头禅了。

再看一个例子。库存系统里有一个库存调整的功能,不同的业务场景对库存的处理方式不一样:

  • 履约扣减:只减理论库存,不动实际库存
  • 期初入库:直接覆盖所有库存数量
  • 盘点调整:先改实际库存,再同步理论库存
  • 调拨/收货/报损:理论库存和实际库存同时增减

如果把这些逻辑全堆在一个方法里用if-else判断,那个方法会膨胀到几百行,而且每次新增一种场景都要在那坨if-else里再加一个分支。改的人心惊胆战,因为怕影响其他分支。

看看高手怎么组织这段逻辑。先定义一个策略接口:

publicinterfaceInventoryAdjustmentHandler{MaterialInventoryAggregateRootexecute(AdjustmentContextcontext);booleanisSupported(AdjustmentContextcontext);}

每种场景一个实现类。履约扣减的处理器:

@ComponentpublicclassFulfillmentAdjustmentHandlerimplementsInventoryAdjustmentHandler{publicstaticfinalList<StatementType>TYPES=List.of(StatementType.PRODUCT_DEDUCTION,StatementType.PRODUCT_RETURNS);@OverridepublicbooleanisSupported(AdjustmentContextcontext){returnTYPES.contains(context.getStatementType());}@OverridepublicMaterialInventoryAggregateRootexecute(AdjustmentContextcontext){// 只扣减理论库存context.getAggregateRoot().fulfillmentAdjustment(context.getDTO());returncontext.getAggregateRoot();}}

聚合根里的调用入口,通过Spring容器自动发现所有处理器,让它们自己判断是否适用:

publicMaterialInventoryAggregateRootadjustment(InventoryAdjustmentDTOdto){Map<String,InventoryAdjustmentHandler>handlers=SpringUtils.getContext().getBeansOfType(InventoryAdjustmentHandler.class);handlers.forEach((key,handler)->{AdjustmentContextcontext=newAdjustmentContext(this,dto,statementType);if(handler.isSupported(context)){handler.execute(context);}});returnthis;}

这种代码有一个特别重要的性质:它没那么容易被破坏。

新增一种库存调整场景,你只需要写一个新的实现类,实现isSupportedexecute两个方法。已有的履约处理器、期初入库处理器、盘点处理器,一行代码都不用动。

新来的同事接手这段代码,他能破坏的范围被限制在他自己写的那个实现类里。他不需要理解其他场景的处理逻辑,也不会因为改错了一行代码导致其他场景出bug。

这就是我说的「精心组织过」的含义。不是为了炫技,是为了让代码在多人协作、长期维护的环境下,尽量少出问题。

水平提升之后,你会觉得他写得真好

这个认知转变的过程,大部分人都会经历。

一开始看到策略模式、工厂模式,觉得绕,觉得不直观。明明可以if-else写在一起,为什么要拆成这么多类?

等你自己维护过一个屎山项目,在一个2000行的方法里找了一下午bug,改一行代码导致三个不相关的功能挂掉之后,你对「代码组织」这件事的理解会完全不一样。

你会开始理解:那些拆成多个小类、每个类职责单一的代码,不是为了好看,是为了让维护者不那么痛苦。你甚至会发自内心地觉得那个人写得真好。

更关键的是,你自己后面也会慢慢写出那样的代码。不是刻意模仿,是你理解了背后的道理之后,自然而然就会那样去组织代码。

这说明你成长了。

从看不懂,到看懂了觉得好,再到自己也能写出来。这是每个开发者技术成长的必经之路。

怎么判断是代码烂还是你水平不够

有些代码确实写得烂,看不懂不是你的问题。怎么区分这两种情况?这张表可以帮你快速判断:

维度代码确实写得烂你水平还不够
命名变量名abc、temp满天飞,类名和功能对不上类名长但语义精确,比如FulfillmentInventoryAdjustmentHandler
结构一个方法500行,什么逻辑都往里塞拆成多个小类,每个类只做一件事
模式没有任何模式,全是if-else和重复代码用了你不认识的设计模式(工厂、策略、模板方法等)
修改成本改一行可能影响十个功能新增功能只需加一个新类,不用动已有代码
一致性同样的事情三个地方三种写法整个模块的代码风格、组织方式高度统一

如果你对照这张表,发现让你困惑的代码在右边这一列全中了:类名虽然长但意思明确,结构拆得很细但每个类职责单一,用了你没见过的模式但改动时不影响其他地方。

那大概率不是代码的问题,是你的知识储备还没覆盖到这里。这不丢人,补起来就好了。

小结

代码组织这件事,表面上看是个编码习惯的问题,深一层想,它反映的是一个开发者对「长期维护成本」的认知水平。

写代码最容易的方式永远是把所有逻辑堆在一起,这样写得最快,当下理解成本最低。代价是后面每次修改都如履薄冰,因为你不知道改这里会不会影响那里。

高手选择多花一些时间做代码的组织和设计,把逻辑拆开、把边界画清楚、把扩展点留好。短期看起来代码多了、类多了、看起来绕了。长期看,每次改动的风险被控制在一个很小的范围内。团队的人来来走走,代码依然能稳定地演进下去。

看不懂这种代码,不用焦虑。先去了解对应的设计模式,理解它要解决的问题,再回来看代码,感受完全不同。等你有一天自己也写出了这样的代码,回头看看自己当初的困惑,你会觉得那就是成长的印记。


最近在知乎出了「应付6000万会员的秒杀系统专栏」和「几亿用户,百万并发的C端商品系统实战」专栏,感兴趣的可以订阅一下。至于知识星球的,可以搜:

  • 老码头的技术浮生录

它是一个能实际帮你解决难题的星球。有问题的,找知心的Sam哥,支持无限次语音一对一解决你遇到的难题。「另外后续我新写的所有对外的付费专栏,在星球内都是免费的,且可以拿到所有源代码。」

知识星球内后续将推出20+个付费专栏,覆盖电商全链路:

选购线用户会员营销线中后台
购物车服务营销系统订单系统
商品服务用户系统支付系统
菜单服务结算服务

从前台选购到中后台结算,星球成员全部免费,后续新增也不额外收费。

我的知乎账号:

  • SamDeepThinking
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 18:12:39

CANN算子测试赛Add报告

【免费下载链接】cann-competitions 本仓库用于 CANN 开源社区各类竞赛、开源课题、社区任务等课题发布、开发者作品提交和展示。 项目地址: https://gitcode.com/cann/cann-competitions 元信息&#xff08;请如实填写&#xff0c;此区块将由组委会脚本自动解析&#xf…

作者头像 李华
网站建设 2026/5/9 18:12:38

观察Taotoken按Token计费模式如何实现精准成本控制

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 观察Taotoken按Token计费模式如何实现精准成本控制 在构建和运营基于大模型的应用时&#xff0c;成本控制是开发者与团队管理者必须…

作者头像 李华
网站建设 2026/5/9 18:11:32

AGI与LLM如何重塑石油天然气行业:从数据治理到智能决策

1. 项目概述&#xff1a;当古老能源遇上前沿智能干了十几年技术&#xff0c;从传统工业自动化到后来的数据分析&#xff0c;再到这两年一头扎进大模型领域&#xff0c;我见过不少技术浪潮。但当我看到“AGI与LLM重塑石油天然气行业”这个命题时&#xff0c;第一反应是&#xff…

作者头像 李华
网站建设 2026/5/9 18:09:31

ChatGPT在Kattis算法题实测:AI编程的强项与局限分析

1. 项目缘起&#xff1a;当AI解题遇上“铁面判官” 最近几个月&#xff0c;我身边不少搞算法竞赛和刷题的朋友都在讨论一个话题&#xff1a;ChatGPT这类大语言模型&#xff0c;到底能不能用来“刷题”&#xff1f;它能理解复杂的算法问题描述吗&#xff1f;能写出能通过严格测试…

作者头像 李华
网站建设 2026/5/9 18:08:50

ACAI平台:基于数据湖与智能调度的MLOps实验管理实践

1. 项目概述&#xff1a;当MLOps遇上数据湖与智能调度在机器学习&#xff08;ML&#xff09;项目从研究走向生产的漫长征途中&#xff0c;实验管理一直是个让人又爱又恨的环节。爱的是&#xff0c;每一次实验都可能是通往更高模型性能的钥匙&#xff1b;恨的是&#xff0c;随着…

作者头像 李华