大家是如何重构已有项目的?怎么进行新的代码/架构设计? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
shinelamla
V2EX    程序员

大家是如何重构已有项目的?怎么进行新的代码/架构设计?

  •  1
     
  •   shinelamla 2023-08-30 09:59:17 +08:00 4899 次点击
    这是一个创建于 851 天前的主题,其中的信息可能已经有所发展或是发生改变。

    马上要重构一个项目,但是涉及的点和业务方都不少,一时间不知道从哪里下手和规划。大佬们有什么重构的经验或者相关的书籍可以分享一下?也是可以代码技巧,代码设计,架构设计方面的分享对我也很重要!!

    30 条回复    2023-08-31 12:29:12 +08:00
    HyperionX
        1
    HyperionX  
       2023-08-30 10:22:38 +08:00   3
    操作角度:重写子模块,切流,把旧模块饿死后下线。
    子模块划分:简单业务后台,调用依赖低于两位数的按业务拆分就行,复杂系统按 DDD 思想基于领域拆好界限上下文,可以参考这个系列文章 https://tkstorm.com/2021/07/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E8%B7%B5ddd%E5%90%8E%E7%9A%84%E4%B8%80%E4%BA%9B%E6%80%9D%E8%80%83/。项目结构组织按照顺手得来,不必非要照抄,数据格式转来转去徒增工作量,保持高内聚低耦合的代码设计思想,找个技术好的单兵做好通用 sdk 开发。
    项目进度把控方面:不建议成立技术专项试图一次花半年全改,这样很难体现你的收益。列好要改的点,每次业务变更的时候多留点 buffer 做重构,做好里程碑奖励和组织激励工作。
    最后推荐阅读《凤凰架构》,再好的架构最终都会腐化。接受会腐化的事实,做好防范工作(代码合入审查),保持组织人员流动健康和业务正常推进(不要 996push ),持续重构和优化。
    tianmalj0613
        2
    tianmalj0613  
       2023-08-30 10:34:51 +08:00   1
    1. 方法支持:
    C4 架构、设计模式(比如服务适配、绞杀、CQRS 等)
    2. 书籍参考
    《重构 改善既有代码的设计》、《代码整洁之道》
    3. 重构的工具和支持
    最好项目有完善的冒烟用例和单元测试,如果有自动化用例,那就大胆重构。以便确定修改后的项目是符合原有的需求的
    4. java 项目的代码质量检查工具
    pmd 、checkstyle
    luzemin
        3
    luzemin  
       2023-08-30 11:09:40 +08:00
    说下个人理解
    1.梳理清楚原有业务
    2.厘清原有实现和调用关系
    3.从相对独立/简单/边缘功能的模块开始重构
    4.基于现有业务和未来一段时间的预测,找出变化点,重构就是针对变化点进行重新设计实现,目标就是隔离变化,不变的部分甚至可以不用重构
    5.朝着“可测试”的方向重构,起码自己重构的代码,写单元测试的时候不能骂人吧
    6.反馈的时候不要说工作是“在重构”,要说重构了什么,带来了什么好处。不然这东西不好量化
    jones2000
        4
    jones2000  
       2023-08-30 11:26:50 +08:00
    为什么要重构, 不要为了重构而重构。 先列出来重构的理由。然后一个一个解决。
    fewspider
        5
    fewspider  
       2023-08-30 11:47:16 +08:00
    可以从这几方面入手:
    1 、解耦,尽量做到只有数据的交互,没有业务的参杂
    2 、重复功能封装
    3 、多余代码精简,包括注释,该删的删,该补充的补充
    4 、单元测试,方便验收,也方便后续维护
    MozzieW
        6
    MozzieW  
       2023-08-30 11:55:28 +08:00
    不知道从哪里下手、规划--》没有重构需求,不需要重构

    知道从哪里下手,要解决什么问题--〉针对问题考虑代码设计、架构
    mydingyan
        7
    mydingyan  
       2023-08-30 12:59:19 +08:00
    我们公司的项目从 net 转到 java 重构了 1 年,全功能回归了 6 轮,比较苦逼

    与预期不一样的是,原本想着功能分模块分批上限,最后 token 不能整两套而一次上线的
    murmur
        8
    murmur  
       2023-08-30 13:00:18 +08:00
    先把需求分析重做了,然后再谈架构问题
    shinelamla
        9
    shinelamla  
    OP
       2023-08-30 13:01:05 +08:00
    @HyperionX 凤凰架构这本书买了!准备先看看 《重构 改善既有代码的设计》
    shinelamla
        10
    shinelamla  
    OP
       2023-08-30 13:01:45 +08:00
    @luzemin 很有帮助
    shinelamla
        11
    shinelamla  
    OP
       2023-08-30 13:02:51 +08:00
    @jones2000 已经梳理出 30+优化项,重构有时候就是太多旧逻辑随着版本迭代而堆积,已经不适用
    shinelamla
        12
    shinelamla  
    OP
       2023-08-30 13:04:04 +08:00
    @murmur 需求分析重做也是个方向,架构基本上是沿用现在的,重构着重是代码逻辑的重构
    ktqFDx9m2Bvfq3y4
        13
    ktqFDx9m2Bvfq3y4  
       2023-08-30 13:18:56 +08:00
    我也在重构公司的屎山系统,我是这么搞的:
    - 先抛出一个概念:独立服务/模块。即服务/模块不依赖于任何其他服务/模块。
    - 然后通过设计保证这些服务/模块可以在任何地方运行(包括控制台里)
    - 然后慢慢将屎山系统的代码迁移到一个个独立的服务/模块中,迁移完之前可以在旧系统继续调用新服务/模块
    - 最终铲平屎山
    crazyTanuki
        14
    crazyTanuki  
       2023-08-30 14:24:13 +08:00
    用微服务概念,把服务一个个抽象出来,再慢慢重构
    lsk569937453
        15
    lsk569937453  
       2023-08-30 14:28:26 +08:00
    如果非得重构一个屎山项目,其实还是很有风险的。

    我们当时是完全接手一个老项目(.Net),经常出问题,老大拍板决定重构(用 java 重构)。
    我们组每个人都领一个子模块,同时还有 2 个核心模块的代码。每天就是读源代码,然后开会代码反讲。
    对于不懂的地方,直接加日志,看下生产环境具体的值。

    重构的顺序: 当时是经常出问题嘛,我们就定位到问题,优先重构有问题的模块。
    验证: 当时是用流量回放进行验证的,每天都进行流量回放,验证了 7 天吧。
    stiangao
        16
    stiangao  
       2023-08-30 14:32:47 +08:00
    重构过 n 个项目,其中一个超大项目,过来告诉你,不要重构
    wangYQ
        17
    wangYQ  
       2023-08-30 16:00:42 +08:00
    能跑着就不要重构,除非必要。除非性能,功能实在没法满足得重构再说,要不然,看屎山代码确实脑袋疼,有得还没有文档传承,有得人都走了,问都没处问
    shinelamla
        18
    shinelamla  
    OP
       2023-08-30 17:06:02 +08:00
    @lsk569937453 流量回放也是我没考虑到的
    shinelamla
        19
    shinelamla  
    OP
       2023-08-30 17:08:30 +08:00
    @wangYQ 我现在就是有着这样的问题...文档过时,注释基本没有,有些业务类型已经不用了但是还是在,有些产品走了新产品上来又推翻,函数里面堆积了一大堆的逻辑最终演变成接近 1000 行的大函数
    shinelamla
        20
    shinelamla  
    OP
       2023-08-30 17:09:51 +08:00
    @Chad0000 总的来说,就是抽象隔离成独立的服务模块,互相先不影响,有点像#14 说的微服务概念,谢谢啦!
    wangYQ
        21
    wangYQ  
       2023-08-30 17:16:19 +08:00
    @shinelamla 重构就是比较麻烦,我的想法是首先要看:
    1.需要不要做服务,不需要不做,没那么大量不做。
    2.把涉及到的业务完全梳理出来,形成文档,多方确认保证业务没有问题。
    3.再确定能不能从全局的视角看一下这个模块的东西能做什么样的设计,能从全局视角看问题和只从这个模块的业务出发得到的设计是两个东西。
    4.从影响程度比较轻的地方入手,尽量将重构的影响降到最低。
    5.重构的东西的测试要更加严格。
    xiangbohua
        22
    xiangbohua  
       2023-08-30 17:31:03 +08:00
    弄一个项目(后台项目)弄了好几个版本,我的理解重构最关键还是业务,业务,业务,说三遍,业务的重新理解、梳理、改规范的规范,改合并流程的合并流程。
    个人的的体会就是,功能加到最后加不动了或者一点需求变更就的改代码,就是因为当前的项目对于业务的理解不够完整,导致无法满足需求的变化。
    其他技术上面的,我觉得就是微观的了,代码不工整的写工整,加急写的代码规整一下;预估下数据量,增长快的提前分库分表;设计模式整起来。
    shinelamla
        23
    shinelamla  
    OP
       2023-08-30 17:36:36 +08:00
    @xiangbohua 谢谢分享!
    shinelamla
        24
    shinelamla  
    OP
       2023-08-30 17:37:26 +08:00
    @wangYQ 和你其中有些想法相似,谢谢分享你的想法~
    NickHopps
        25
    NickHopps  
       2023-08-30 20:36:13 +08:00
    1 、确定重构的目标:功能解耦?性能优化?
    2 、深入了解业务:不清楚业务的每个细节很难保证能想出合适的方案
    3 、了解常用的重构手法:福勒的《重构》,当成工具书,用到什么看什么
    4 、确定是否需要 DT 守护:取决于业务的重要程度、重构的工作量和给的工作量
    5 、实施重构:拆解重构目标,一个点一个点思考重构的方案
    ypfJavaCoder
        26
    ypfJavaCoder  
       2023-08-30 21:43:19 +08:00   1
    下面是个人纯经验分享,希望对你有帮助。

    重构目标:之前代码已成为屎山,维护起来牵一发而动全身,现在需要新写代码来提升代码的可维护性、可扩展性、可读性、可观测性。下面是一些技巧:
    - 可维护性:避免过度抽象,类、方法、接口满足单一原则;统一规范(某个概念要全链路命名一致,DTO 、BO 、DO 每一层都要定义单独的对象出来便于后续不同层级加字段时不影响其他层级);数据库表预留扩展性字段;
    - 可扩展性:如果业务频繁变动,是否可以把业务流程抽象为「配置化 + 核心框架」,后续只需要变更配置和新实现一些约定的接口就行,而不需要改动核心框架,类似于 Spring 帮我们实现了 IoC 的核心框架,我们想扩展只需要配置化或实现扩展点接口( BeanPostProcessor )即可。
    - 可读性:写方法要满足单一抽象层次;复杂流程注释写好 1 、2 、3 流程的 what 、why 、how ;
    - 可观测性:打好日志;接口入口处统一做好基于错误码(业务异常抛出的特定错误码)的阈值监控,系统异常直接钉钉告警。

    重构 SOP:
    * 事前:
    * 重构代码要对整个业务逻辑有全面的了解,多问几个 why 。
    * 要彻底搞通「重构代码逻辑如何闭环、新老数据差异点、新老字段含义映射」这些方面,不能一知半解。
    * 对使用的依赖(接口、工具方法)要熟悉它的逻辑。
    * 日志打好、打全。
    * 测试用例要覆盖全。
    * 事中:
    * 做好 360 无死角监控告警,且要有灰度策略。
    * 灰度放量后仔细观察日志(错误日志)、DB 表中的核心字段(单号、金额、币种、状态),核查字段应不应该有值(有值都有值,要没值都没值)、值对不对(长度、格式、金额是最小单位还是原金额等要求)。
    * 事后:
    * 出现问题要优先考虑业务影响(统计受影响的订单数、金额,客户感知),然后再去想最坏的打算,如何补救。

    重构注意事项
    1. 重构时只搞一部分逻辑,不要把多个功能同时重构。要进行任务拆解,按照计划有节奏来。如果系统太复杂,可以拆分为多期,分几期去上线。
    > 任务拆分: https://mp.weixin.qq.com/s/lY1djkQGK0e5yMIm4ZnkbQ
    2. 重构的时间节奏是否和业务发展相匹配。
    3. 先专注于跑通主流程,再钻研细节。
    4. 以始为终,做的过程中始终回想重构的目标,避免偏离方向。
    Potatooo
        27
    Potatooo  
       2023-08-30 21:54:35 +08:00
    看 OP 的描述是还没有开始,那么最先要做的事情是想办法弄清楚业务流程。
    找业务的主管部门的老人们买杯奶茶去了解系统是为了解决什么问题的,有哪些需求当初是怎么实现的。
    业务了解了,怎么重构,什么设计模式你自然可以信手拈来。
    还有一点需要注意的是,要做好紧急预案,负责系统的重构代码肯定会导致业务出问题,你要想好重构系统有 bug 要如何对应,你可不要和我说加班对应。
    qiaobeier
        28
    qiaobeier  
       2023-08-30 22:08:35 +08:00
    怎么新技术怎么来(带薪学习美滋滋)
    怎么复杂怎么来
    shinelamla
        29
    shinelamla  
    OP
       2023-08-31 12:25:26 +08:00
    @BarackLee 有问题就回滚,数据层不会动,不需要加班。先出一个大体的方案,了解下失眠上的实现,再看看怎么实现吧
    shinelamla
        30
    shinelamla  
    OP
       2023-08-31 12:29:12 +08:00
    @ypfJavaCoder 感谢,虽然项目不是 java 的,但都很受用,谢谢分享
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3209 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:04 PVG 08:04 LAX 16:04 JFK 19:04
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86