![程序员的底层思维](https://wfqqreader-1252317822.image.myqcloud.com/cover/270/46841270/b_46841270.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
1.4.4 抽象缺失之重复代码
如果说抽象源于对共性的提取,那么代码中的重复代码是不是就意味着抽象缺失呢?
重复代码是典型的代码坏味道,其本质问题就是抽象缺失。使用“Ctrl+C”加“Ctrl+V”的工作习惯导致没有对共性代码进行抽取,或者虽然抽取了,但没有设置一个合适的名字,没有正确地反映这段代码所体现的抽象概念,这些都属于抽象不到位。
有一次,我在审查团队代码的时候,发现有一段组装搜索条件的代码,如图1-5所示,这段代码在几十个地方都有重复。
![](https://epubservercos.yuewen.com/1F31CC/26126228301725106/epubprivate/OEBPS/Images/42977_29_1.jpg?sign=1738906638-tWfxJtnkq1EC3QHbnakgF77p3gLlCz6u-0-5f2a913018b51e9206ae449a9329a5c9)
图1-5 组装搜索条件的重复代码
这个搜索条件比较复杂,是以元数据的形式存在于数据库中的,因此组装的过程分为两步。
(1)从缓存中把搜索条件列表取出来。
(2)遍历这些条件,将搜索的值填充进去。
![](https://epubservercos.yuewen.com/1F31CC/26126228301725106/epubprivate/OEBPS/Images/42977_29_2.jpg?sign=1738906638-XiEFYSldJVZd6apJUXMVXdhqIyKWmHRG-0-1f7b40e293595472bface4f5cb220c29)
简单的重构无外乎就是把这段代码提取出来,放到一个Util类中以便复用。然而我认为这样的重构只是完成了一半的工作——只是做了简单的归类,并没有做抽象提炼。
简单分析,不难发现,此处我们缺失了两个概念:一个是用来表达搜索条件的类——SearchCondition,另一个是用来组装搜索条件的类——SearchConditionAssembler。只有配合命名,显性化地将这两个概念表达出来,才是一个完整的重构。
重构后,搜索条件的组装会变成一种非常简洁的形式,几十处的代码复用只需要引用SearchConditionAssembler就好了:
![](https://epubservercos.yuewen.com/1F31CC/26126228301725106/epubprivate/OEBPS/Images/42977_30_1.jpg?sign=1738906638-AIXtmglP2ReeG8HDePqPyR5tyjbu55H1-0-242d436cd20258ea92f4808de9419204)
由此可见,提取重复代码只是重构工作的第一步。对重复代码进行概念抽象,寻找有意义的命名才是我们工作的重点。
因此,每次遇到重复代码需要重构的时候,你都应该感到兴奋,这是一次锻炼抽象能力的绝佳机会。