news 2026/4/15 13:16:20

代码重构 —— 读后感

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码重构 —— 读后感

前言:推荐大家阅读 Martin Fowler的《重构——改善既有代码的设计》第2版。本文谈一谈本人阅读几章节之后的一点理解。

目录

一、什么是重构

二、为何需要重构

1)使代码易于理解

2)使代码便于扩展维护

3)使代码不易变质

三、何时需要重构

四、重构的前提

五、重构的常用方法

1)提取重复代码为函数

2)优化命名

3)简化复杂条件判断

4)拆分高耦合类

六、重构与性能优化的关系


一、什么是重构

重构的是指在不改变代码外部行为的前提下,优化内部结构,让代码更易维护、扩展和理解。

二、为何需要重构

1)使代码易于理解

可能是为了节省时间,很多开发者没有写注释的习惯。在复杂的庞大系统编程中,重构告诉我们 需要为复杂函数写清楚注释,便于后面新人快速接手。

2)使代码便于扩展维护

我们平时开发项目时,由于项目周期较短,资源紧张等客观因素,使得我们的开发只关注功能的实现与完成,可能中间出现了重复代码、无用代码、危险的指针等。当有新的需求或是修改bug,可能都在原有代码结构中直接进行修改,使得代码堆砌,变得杂乱,难以扩展维护

3)使代码不易变质

有一个经典的”破窗理论“,即:如果一扇窗户破了,如果你不及时去修补,时间长了,经过的路人可能认为这里一直是个破烂的地方,可以丢垃圾,而后很多人在这里附近丢垃圾,导致成了垃圾堆。代码也是一样,如果不及时重构,那么就会变成垃圾,堆积如山,慢慢变质。

三、何时需要重构

代码出现“坏味道”的时候可能就需要重构了。

“坏味道”包括 变量/函数命名不清晰、耦合度高、大量的裸指针、条件分支过于复杂等。

事不过三,三则重构:如果你第一次改一处代码觉得可以下手,第二次修改勉强可以下手,第三次难以下手,那么这就提醒你是时候需要进行重构了。

四、重构的前提

想要重构,必须得先有可以自测试的代码。用书中的观点便是:重构的第一块基石是自测试代码。前面说过重构是在不改变代码外部行为的前提下进行的,那如何才能保证不改变代码外部行为呢?答案是只能通过自测试。因此在没有自测试代码之前,不能随意开始重构。

五、重构的常用方法

1)提取重复代码为函数

避免重复造轮子,将公有部分提炼成函数。

重构前:

#include <iostream> #include <cmath> using namespace std; int main() { // 计算圆1的面积和周长 double r1 = 5.0; double area1 = M_PI * r1 * r1; double circumference1 = 2 * M_PI * r1; cout << "圆1面积:" << area1 << ",周长:" << circumference1 << endl; // 计算圆2的面积和周长(重复代码) double r2 = 8.0; double area2 = M_PI * r2 * r2; double circumference2 = 2 * M_PI * r2; cout << "圆2面积:" << area2 << ",周长:" << circumference2 << endl; return 0; }

重构后:

#include <iostream> #include <cmath> using namespace std; // 提取重复逻辑为函数,复用性提升 double calculateCircleArea(double radius) { return M_PI * radius * radius; } double calculateCircleCircumference(double radius) { return 2 * M_PI * radius; } int main() { double r1 = 5.0; cout << "圆1面积:" << calculateCircleArea(r1) << ",周长:" << calculateCircleCircumference(r1) << endl; double r2 = 8.0; cout << "圆2面积:" << calculateCircleArea(r2) << ",周长:" << calculateCircleCircumference(r2) << endl; return 0; }

2)优化命名

清晰的命名能够显著提高代码的可读性。

重构前:

#include <iostream> using namespace std; // 函数名模糊,参数名无意义 int f1(int a, int b) { int c = a * b; // c的含义不明确 if (c > 100) { return c - 10; } else { return c; } } int main() { int x = 15; int y = 8; cout << f1(x, y) << endl; // 不知道f1是做什么的 return 0; }

重构后:

#include <iostream> using namespace std; // 函数名+参数名语义化,一眼能懂功能 int calculateDiscountedProductTotal(int unitPrice, int quantity) { int totalPrice = unitPrice * quantity; // 超过100减10的逻辑明确标注 if (totalPrice > 100) { return totalPrice - 10; } else { return totalPrice; } } int main() { int phonePrice = 15; int buyCount = 8; cout << calculateDiscountedProductTotal(phonePrice, buyCount) << endl; return 0; }

3)简化复杂条件判断

重构前:

#include <iostream> #include <string> using namespace std; bool canLogin(string username, string password, int age, bool isVerified) { // 条件表达式冗长,逻辑不清晰 if (username != "" && password.length() >= 6 && age >= 18 && isVerified == true) { return true; } else { return false; } } int main() { cout << boolalpha << canLogin("zhangsan", "123456", 20, true) << endl; return 0; }

重构后:

#include <iostream> #include <string> using namespace std; // 提取子条件为语义化函数,简化主逻辑 bool isUsernameValid(string username) { return !username.empty(); } bool isPasswordValid(string password) { return password.length() >= 6; } bool isAdult(int age) { return age >= 18; } bool canLogin(string username, string password, int age, bool isVerified) { // 条件逻辑清晰,一眼能懂判断维度 return isUsernameValid(username) && isPasswordValid(password) && isAdult(age) && isVerified; } int main() { cout << boolalpha << canLogin("zhangsan", "123456", 20, true) << endl; return 0; }

4)拆分高耦合类

如:一个类同时处理网络请求、数据解析、日志打印。

重构前:

#include <iostream> #include <string> // 高耦合:一个类承担多个职责 class UserService { public: void getUserInfo(const std::string& userId) { // 1. 网络请求(职责1) std::string rawData = "userId=" + userId + "&name=zhangsan&age=20"; std::cout << "发送网络请求,获取原始数据:" << rawData << std::endl; // 2. 数据解析(职责2) std::string name = "zhangsan"; int age = 20; // 3. 日志打印(职责3) std::cout << "[LOG] 解析用户信息:name=" << name << ", age=" << age << std::endl; // 4. 业务逻辑 std::cout << "用户信息:" << name << "(" << age << "岁)" << std::endl; } }; int main() { UserService service; service.getUserInfo("1001"); return 0; }

重构后:

#include <iostream> #include <string> // 职责1:网络请求 class NetworkClient { public: std::string requestUserRawData(const std::string& userId) { std::string rawData = "userId=" + userId + "&name=zhangsan&age=20"; std::cout << "发送网络请求,获取原始数据:" << rawData << std::endl; return rawData; } }; // 职责2:数据解析 class UserDataParser { public: struct UserInfo { std::string name; int age; }; UserInfo parse(const std::string& rawData) { // 简化解析逻辑,实际可使用正则/字符串分割 return {"zhangsan", 20}; } }; // 职责3:日志打印 class Logger { public: static void printUserLog(const UserDataParser::UserInfo& info) { std::cout << "[LOG] 解析用户信息:name=" << info.name << ", age=" << info.age << std::endl; } }; // 职责4:业务逻辑(依赖其他类,但耦合度低) class UserService { private: NetworkClient networkClient; UserDataParser parser; public: void getUserInfo(const std::string& userId) { std::string rawData = networkClient.requestUserRawData(userId); UserDataParser::UserInfo info = parser.parse(rawData); Logger::printUserLog(info); std::cout << "用户信息:" << info.name << "(" << info.age << "岁)" << std::endl; } }; int main() { UserService service; service.getUserInfo("1001"); return 0; }

六、重构与性能优化的关系

有部分开发者可能认为重构一定是性能优化的,其实不然。

重构的首要目标不是提升性能,但良好的重构会让性能优化更易实现。

结束语:以上仅是个人对重构的一些理解。文中提到的重构手法只列举了一些简单常见的,欢迎读者根据自身项目经验在评论区补充留言。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 17:44:24

吐血整理,13年老鸟性能测试理解误区分析,一篇带你上手...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、性能测试的目的…

作者头像 李华
网站建设 2026/4/15 7:39:41

10、企业管理中的网络资源管理与操作指南

企业管理中的网络资源管理与操作指南 1. 企业管理概述 企业每年会花费数百万美元在打包应用程序和人力上,以确保其计算环境像精密调整的引擎一样运行。然而,大多数第三方解决方案虽提供企业管理工具,但往往带有花哨的报告功能,实际功能却有限,且获得预算批准来采用有用的…

作者头像 李华
网站建设 2026/4/15 7:39:44

Wayfair家居电商平台研究指南:十款实用工具助力垂直市场分析

在专注于家居家具的垂直电商领域&#xff0c;Wayfair凭借其庞大的产品目录、供应商集成模式与对大件物流的深度把控&#xff0c;成为观察耐用消费品在线零售、B2B2C平台运营及复杂供应链管理的代表性样本。该平台为研究高客单价、长决策周期品类的电商策略、可视化技术应用及端…

作者头像 李华
网站建设 2026/4/15 7:37:55

Langchain-Chatchat构建银行理财产品说明查询系统

基于Langchain-Chatchat构建银行理财产品智能问答系统 在金融行业数字化转型加速的今天&#xff0c;银行客户和一线员工对信息获取的实时性与准确性要求越来越高。尤其是理财产品说明书这类文档——内容专业、结构复杂、更新频繁&#xff0c;往往几十页PDF中只有一两句话回答某…

作者头像 李华
网站建设 2026/4/15 7:38:12

24、电脑问题预防与儿童电脑使用监管指南

电脑问题预防与儿童电脑使用监管指南 1. 系统问题预防相关要点 在使用设备时,当收到安装软件的建议时,点击或轻触“安装”,会自动启动缺失软件的下载和安装过程。同时,操作中心显示的消息有颜色编码规则:红色表示非常重要,不可忽视的消息;黄色表示建议类消息,若认为不…

作者头像 李华
网站建设 2026/4/15 7:37:30

27、Windows 8:数据加密、触摸操作与数学输入全攻略

Windows 8:数据加密、触摸操作与数学输入全攻略 1. 加密可移动驱动器的使用与管理 在使用可移动驱动器时,数据安全是至关重要的。通过 BitLocker 加密,我们可以确保存储在 USB 记忆棒或外部硬盘驱动器等设备上的数据不被未经授权的人员访问。 1.1 完成加密后的操作 当你…

作者头像 李华