别人写的代码看不懂,到底是谁的水平有问题
你突然看到某段代码用了工厂模式第一反应可能是有必要吗直接new一个对象不行吗干嘛「故意」增加阅读难度其实不是这样的当你接触过的高手多了后你会自然而然的认为高手的代码确实不太容易看懂尤其你水平还不够的时候。我不是说你菜只是每个人都会经历过这个阶段的。关键在于你得分清楚一件事到底是代码本身写得烂还是你的知识面暂时还覆盖不到这里。你觉得没必要可能是你还没遇到那个场景如果你构造的对象只是简单地设置几个属性确实没必要用工厂。直接用构造方法或者Builder就够了。问题出在另一种场景构造一个业务对象的过程本身就很复杂。拿门店进销存系统中的物料盘点模块举例。创建一张盘点单据需要做这些事情根据模板ID去查盘点模板拿到模板里配置的名称、类型、盘点日期规则调用编码生成服务按照业务规则生成单据编号把提交过来的物料数据逐条转换成明细实体把以上所有数据组装成一个完整的聚合根对象这不是简单地new一个对象然后set几个字段。整个构造过程涉及到外部服务调用、数据库查询、业务规则计算。如果这些逻辑散落在调用方的代码里那每个需要创建盘点单据的地方都得重复写一遍。用工厂模式封装这些构造逻辑代码大概长这样ComponentpublicclassStocktakingDocsFactory{privatefinalCodeGeneratorServicecodeGeneratorService;privatefinalStocktakingTemplateRepositorytemplateRepository;publicStocktakingDocsAggregateRootcreate(SubmitStocktakingCommandcommand){// 查询模板获取名称、类型、日期规则StocktakingTemplatetemplatetemplateRepository.getById(command.getTemplateId());// 生成单据编号StringcodecodeGeneratorService.generate(ModuleEnum.STOCKTAKING);// 组装明细ListStocktakingItemEntityitemsbuildItems(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{publicstaticfinalListStatementTypeTYPESList.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){MapString,InventoryAdjustmentHandlerhandlersSpringUtils.getContext().getBeansOfType(InventoryAdjustmentHandler.class);handlers.forEach((key,handler)-{AdjustmentContextcontextnewAdjustmentContext(this,dto,statementType);if(handler.isSupported(context)){handler.execute(context);}});returnthis;}这种代码有一个特别重要的性质它没那么容易被破坏。新增一种库存调整场景你只需要写一个新的实现类实现isSupported和execute两个方法。已有的履约处理器、期初入库处理器、盘点处理器一行代码都不用动。新来的同事接手这段代码他能破坏的范围被限制在他自己写的那个实现类里。他不需要理解其他场景的处理逻辑也不会因为改错了一行代码导致其他场景出bug。这就是我说的「精心组织过」的含义。不是为了炫技是为了让代码在多人协作、长期维护的环境下尽量少出问题。水平提升之后你会觉得他写得真好这个认知转变的过程大部分人都会经历。一开始看到策略模式、工厂模式觉得绕觉得不直观。明明可以if-else写在一起为什么要拆成这么多类等你自己维护过一个屎山项目在一个2000行的方法里找了一下午bug改一行代码导致三个不相关的功能挂掉之后你对「代码组织」这件事的理解会完全不一样。你会开始理解那些拆成多个小类、每个类职责单一的代码不是为了好看是为了让维护者不那么痛苦。你甚至会发自内心地觉得那个人写得真好。更关键的是你自己后面也会慢慢写出那样的代码。不是刻意模仿是你理解了背后的道理之后自然而然就会那样去组织代码。这说明你成长了。从看不懂到看懂了觉得好再到自己也能写出来。这是每个开发者技术成长的必经之路。怎么判断是代码烂还是你水平不够有些代码确实写得烂看不懂不是你的问题。怎么区分这两种情况这张表可以帮你快速判断维度代码确实写得烂你水平还不够命名变量名abc、temp满天飞类名和功能对不上类名长但语义精确比如FulfillmentInventoryAdjustmentHandler结构一个方法500行什么逻辑都往里塞拆成多个小类每个类只做一件事模式没有任何模式全是if-else和重复代码用了你不认识的设计模式工厂、策略、模板方法等修改成本改一行可能影响十个功能新增功能只需加一个新类不用动已有代码一致性同样的事情三个地方三种写法整个模块的代码风格、组织方式高度统一如果你对照这张表发现让你困惑的代码在右边这一列全中了类名虽然长但意思明确结构拆得很细但每个类职责单一用了你没见过的模式但改动时不影响其他地方。那大概率不是代码的问题是你的知识储备还没覆盖到这里。这不丢人补起来就好了。小结代码组织这件事表面上看是个编码习惯的问题深一层想它反映的是一个开发者对「长期维护成本」的认知水平。写代码最容易的方式永远是把所有逻辑堆在一起这样写得最快当下理解成本最低。代价是后面每次修改都如履薄冰因为你不知道改这里会不会影响那里。高手选择多花一些时间做代码的组织和设计把逻辑拆开、把边界画清楚、把扩展点留好。短期看起来代码多了、类多了、看起来绕了。长期看每次改动的风险被控制在一个很小的范围内。团队的人来来走走代码依然能稳定地演进下去。看不懂这种代码不用焦虑。先去了解对应的设计模式理解它要解决的问题再回来看代码感受完全不同。等你有一天自己也写出了这样的代码回头看看自己当初的困惑你会觉得那就是成长的印记。最近在知乎出了「应付6000万会员的秒杀系统专栏」和「几亿用户,百万并发的C端商品系统实战」专栏感兴趣的可以订阅一下。至于知识星球的可以搜老码头的技术浮生录它是一个能实际帮你解决难题的星球。有问题的找知心的Sam哥支持无限次语音一对一解决你遇到的难题。「另外后续我新写的所有对外的付费专栏在星球内都是免费的且可以拿到所有源代码。」知识星球内后续将推出20个付费专栏覆盖电商全链路选购线用户会员营销线中后台购物车服务营销系统订单系统商品服务用户系统支付系统菜单服务结算服务从前台选购到中后台结算星球成员全部免费后续新增也不额外收费。我的知乎账号:SamDeepThinking
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2598318.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!