V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
这是一个专门讨论 idea 的地方。

每个人的时间,资源是有限的,有的时候你或许能够想到很多 idea,但是由于现实的限制,却并不是所有的 idea 都能够成为现实。

那这个时候,不妨可以把那些 idea 分享出来,启发别人。
wellR
V2EX  ›  奇思妙想

重构 Java 屎山代码的一种妄想,大佬们评估一下

  •  
  •   wellR · 212 天前 · 2372 次点击
    这是一个创建于 212 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前提:

    • 假设能在 java 运行期记录方法执行轨迹

    场景:

    • 接手的代码需要加入新功能,有重构老代码的需求,
    • 比如现在有方法 method ,这个方法承担 4 个业务,代码混乱/耦合严重
    • 想将 method 拆分为 4 个,记作 method_1/method_2/method_3/method_4
    • 人工去读代码痛苦且低效,期望可以使用代码完成拆分

    理论:

    1. java 方法在编译期会生成 AST ,每个代码结构对应语法树中的节点 node ,AST 的分支也就对应方法的代码分支逻辑,比如 if/else 结构表现在 AST 中就是一个分叉,会有两个子分支
    2. 记录一次方法调用中所有执行过的 node ,这些 node 的集合 nodes 就是这次调用实际执行的代码分支
    3. 可以将 nodes 转换为代码,就是这次调用的源码

    问题

    • 如何在 java 运行期标注出某一个方法调用过程实际执行过的 AST 节点集?
    • AST 的节点集如何转化为可执行的代码?
    18 条回复    2024-05-30 10:07:08 +08:00
    monmon
        1
    monmon  
       212 天前
    感觉你在找的可能是 Intellij Profile ? By the way...如果你这个 method 的执行效率不是特别离谱,没人吐槽它慢,业务能跑最好别去动它,屎山这玩意谁沾谁脏😅
    jamel
        2
    jamel  
       212 天前
    链路追踪?
    yuanmomo
        3
    yuanmomo  
       212 天前 via iPhone
    当年红岭创投重构.Net 到 Java ,花钱请了阿里的外援,全线使用阿里云。当时预计半年能搞完,我给他们预计的是,一年都搞完就不错了。结果最后花了一年多,上线的时候预计 8 小时,最后好像接近 20 小时吧。

    一个项目,要重构,太多的先决条件了,最重要的就是测试覆盖率。如果测试用例不够,我是绝逼不重构的。
    wellR
        4
    wellR  
    OP
       212 天前
    @jamel 嗯,与链路追踪很相似,颗粒度更小,细致到表达式,到某行代码的追踪
    wellR
        5
    wellR  
    OP
       212 天前
    @yuanmomo 对对, 要有完备的测试用例与懂业务的人协助,否则没完没了
    wellR
        6
    wellR  
    OP
       212 天前
    @monmon 接手的项目,没有文档,反而要我们开发读源码输出文档,性能不是问题。有出那么些接口负责多种业务,一堆一堆的逻辑分支,头疼,开 debugger 才勉强搞明白些。说起来 java 的 Debugger 应该是能拿到我说的“代码追踪”数据的,怎么才能拿到呢
    jamel
        7
    jamel  
       212 天前   ❤️ 1
    阿里云的 arms 可以到方法 到类,还有性能数据,很像火焰图了
    Dream95
        8
    Dream95  
       212 天前   ❤️ 1
    Jacoco ?
    wellR
        9
    wellR  
    OP
       212 天前
    楼上的回答启发我了,这跟单元测试中的代码覆盖率很接近啊,只不过目标不一样,我是为了抽离代码,关注指定方法在指定输入下的实际执行的代码,而排除其它的逻辑分支的视觉干扰,降低心智负担。
    monmon
        10
    monmon  
       212 天前
    idea 的 SequenceDiagram 插件应该可以满足你的需求
    monmon
        11
    monmon  
       212 天前   ❤️ 1
    @monmon SequenceDiagram 可以解决问题一自动分析出代码的所有调用过程,但是你想要代码自动拆分 method ,这个可能不太好实现
    wellR
        12
    wellR  
    OP
       212 天前
    @monmon 好的,多谢回复,我去了解了解
    ukpkmk
        13
    ukpkmk  
       212 天前
    <<精简代码实战:核心系统缩减 80%代码>>
    https://mp.weixin.qq.com/s/30PHdlnGZ4lGm3H5VeLRWQ
    以前看过的一个文章和你说的很像,也是经过一个月的随机采样,采集到 46 万流量,以此来对系统代码进行染色,得到有效函数
    SoloCompany
        14
    SoloCompany  
       212 天前
    实际上最简单的做法是把 method 直接复制 4 份, 然后把流程控制变量变成常量, 利用 IDE 静态分析删除 dead code, 剩余的 duplicate code 通常也能被分析出来, 根据提示 extract method
    wellR
        15
    wellR  
    OP
       212 天前
    @ukpkmk 谢谢了,文章我看过了,“代码染色”很贴切的描述
    tikazyq
        16
    tikazyq  
       210 天前
    用图论去解决屎山问题固然很酷,但投入产出比不一定值得,特别是需要重构的代码量没到一定量级的时候。几十百来个文件需要重构的话,可能还不如人海战术重写逻辑。

    还有,现在 GPT 都这么大窗口了,直接扔进去加合理的 prompt 理论上也可能有低成本的收获。

    最后,养成良好的编程习惯和团队文化(例如 TDD 、代码审核),比硬啃屎山更有效和稳定。屎山代码产生的根本原因,通常来自于急功近利的老板和不够负责的技术领导。
    wellR
        17
    wellR  
    OP
       210 天前
    @SoloCompany 这也是个法子
    wellR
        18
    wellR  
    OP
       210 天前
    java 的 debugger 能获取的信息很丰富,似乎可以支撑代码分割或者代码染色的实现
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5807 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:40 · PVG 10:40 · LAX 18:40 · JFK 21:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.