当前位置: 首页 > news >正文

【代码坏味道】膨胀类 Bloaters

🐘 长方法(Long Method)

📍 什么是长方法?

一个函数(方法)写得太长了,比如超过了 10 行代码,就要开始警惕了。

❗ 为什么不好?

  • 一开始只是加两行代码,觉得“没必要单独写个函数吧”,但一直加一直加,就变成“面条式代码”。
  • 别人读这个函数会很费劲,自己写的时候也难维护。

✅ 怎么解决?

  • 如果你想在方法里加注释解释某段逻辑,说明这段代码应该拆出去成单独方法。
  • 哪怕是只有一行代码,如果需要说明,也应该单独封装成一个有意义的方法。

🔨 可以使用的技巧:

  • 提取方法(Extract Method)

  • 如果受限于变量,可以使用:

    • 用查询代替临时变量(Replace Temp with Query)
    • 引入参数对象(Introduce Parameter Object)
    • 保留整个对象(Preserve Whole Object)

💰 好处:

  • 小方法的代码更容易看懂、改动风险小。
  • 重复代码也更容易被发现和删除。
  • 不用担心“方法太多影响性能”,其实几乎没影响。

🏢 大类(Large Class)

📍 什么是大类?

一个类(类似于一块代码模块)里面包含太多变量、方法、代码行

❗ 为什么不好?

  • 类一开始很小,但功能一多,就越写越大。
  • 程序员偷懒,喜欢往原来的类里加功能,而不是重新建一个类。

✅ 怎么解决?

  • 把类拆成更小的类,一个类只负责一种职责。

  • 使用:

    • 提取类(Extract Class)
    • 提取子类(Extract Subclass)
    • 提取接口(Extract Interface)
    • 如果是界面类太大,考虑拆成“界面类 + 数据类”

💰 好处:

  • 更容易记住和管理类里的内容。
  • 避免重复代码,代码结构更清晰。

⚙️ 原始类型痴迷(Primitive Obsession)

📍 什么是“痴迷”原始类型?

就是你过度使用 int、string 这些基本类型,而不愿意封装成对象。

比如:

  • 电话号码用 string,金额用 float,而不是专门建个 PhoneNumberMoney 类。
  • 用常量 1, 2, 3 来表示权限等级,而不是定义角色类。

❗ 为什么不好?

  • 这些基本类型不好加规则,也不好扩展。
  • 常量意义不清晰,还容易出 bug。

✅ 怎么解决?

  • 使用对象代替基本类型,比如把 price 封装成 Money 类。
  • 用类表示状态、角色,而不是数字或字符串。
  • 参数多时,用类打包(Introduce Parameter Object)

💰 好处:

  • 代码更灵活,规则清晰。
  • 更容易找到重复代码,修改也集中,不怕出错。

📬 长参数列表(Long Parameter List)

📍 什么是长参数列表?

如果一个方法需要传超过 3~4 个参数,那就太多了。

❗ 为什么不好?

  • 参数太多让方法调用变复杂,容易传错。
  • 有时为了减少依赖,把对象提前创建好再传进来,结果传了一堆参数。

✅ 怎么解决?

  • 如果多个参数来自一个对象,可以直接传这个对象(Preserve Whole Object)。
  • 如果来自不同地方,但经常一起用,就打包成一个类(Introduce Parameter Object)。

💰 好处:

  • 方法调用更简洁,代码更清晰。
  • 还能发现重复逻辑,方便提取成公共方法。

🧱 数据泥团(Data Clumps)

📍 什么是数据泥团?

如果你在多个地方看到总是成组出现的变量(比如数据库连接的 host、port、user、pass),那就是一个“数据泥团”。

❗ 为什么不好?

  • 这些变量成组出现,一变就全变,容易出错。
  • 多次复制粘贴,非常不优雅。

✅ 怎么解决?

  • 把这些成组变量封装进一个类,比如 DbConfig
  • 如果是方法参数太多,也可以用“参数对象”。

💰 好处:

  • 所有相关操作集中在一个类中,更好维护。
  • 大大减少代码行数,也避免写重复的东西。

✅ 小结:什么时候该重构?

异味类型表现处理方式
长方法方法超过 10 行拆方法、封装注释
大类类里方法、变量太多拆类、抽子类/接口
原始类型痴迷int/string 代替对象用对象封装、引入类型
长参数列表传参超过 4 个保留整个对象或参数对象
数据泥团相同变量反复出现抽成类统一管理

相关文章:

  • Go语言的context
  • 《高等数学》(同济大学·第7版) 第一节《映射与函数》超详细解析
  • 【算法】递归与分治策略
  • Cesium快速入门到精通系列教程一
  • 【Linux】进程地址空间揭秘(初步认识)
  • 【计算机网络】 ARP协议和DNS协议
  • 计算机网络物理层基础练习
  • 【CC协议】知识共享许可协议(Creative Commons Licenses)体系解析
  • Python 中Vector类的格式化实现,重点拆解其超球面坐标系的设计精髓
  • 15分钟讲解所有较知名编程语言
  • DAY 16 numpy数组与shap深入理解
  • GD32F103系列工程模版创建记录
  • js数据类型有哪些?它们有什么区别?
  • 如何找到一条适合自己企业的发展之路?
  • Agent开发详解
  • 【Qt】Bug:findChildren找不到控件
  • 【Python训练营打卡】day40 @浙大疏锦行
  • 机器学习03-色彩空间:RGB、HSV、HLS
  • 图像修复的可视化demo代码
  • atapi!IdeReadWrite函数分析下之Send read command
  • 深圳专业商城网站设计/品牌策划推广方案
  • .net core 网站开发/软件开发外包
  • 海门做网站公司/东莞seo网络公司
  • wordpress怎么完成/郑州关键词优化费用
  • 做玻璃的网站/搜索优化指的是什么
  • wordpress网站支持中文注册/上海职业技能培训机构