php怎样做网站,专业装修设计网站,万商云集(成都)科技股份有限公司,英文网站建设中作者 | 刘俊启 导读 在软件开发中#xff0c;经常会遇到一些代码问题#xff0c;例如逻辑结构复杂、依赖关系混乱、代码冗余、不易读懂的命名等。这些问题可能导致代码的可维护性下降#xff0c;增加维护成本#xff0c;同时也会影响到开发效率。这时通常通过重构的方式对已…
作者 | 刘俊启 导读 在软件开发中经常会遇到一些代码问题例如逻辑结构复杂、依赖关系混乱、代码冗余、不易读懂的命名等。这些问题可能导致代码的可维护性下降增加维护成本同时也会影响到开发效率。这时通常通过重构的方式对已有代码结构进行改进和优化。在重构的工作中大部分的工作是人工的方式完成是一个耗时且容易出错的过程。对于研发人员来讲在不改变软件的功能和行为的前提下保证质量和效率完成对已有功能的重构是一个极大的挑战。本系列以Python实现自动化的工具支持代码重构过程的实践。 全文5529字预计阅读时间14分钟。 在上一篇《通过Python脚本支持OC代码重构实践一模块调用关系分析》的内容中重点介绍了使用Python实现模块调用关系的分析并以.csv格式文件输出导入到excel中评估重构影响面及每个数据项重构方式在重构编码工作启动前明确了具体的工作及重构之后的收益这对于立项的人力投入的决策会起到很关键的作用特别是当团队资源稀缺时把要做的事情讲清楚是一件很重要的事情。
同时也在上篇内容中提到技术层面先实现一个模块间数据项通讯的机制本系列文章中以数据通路代指支持数据项不需要公开也可以被其它的组件中的模块读写。基于数据通路的实现将XXXSetting模块接入数据通路就可以解决因为XXXSetting模块中的数据项变更而带来的接口不兼容变更的问题也会降低上层的依赖方组件二次的发布次数间接的提升XXXSetting模块数据项相关研发需求的研发效率。
在XXXSetting模块数据项接入到数据通路过程以百为量级的数据项需要逐项的按照数据通路的标准进行重构手工的重构方式成本高出错概率高测试时需要逐项验证成本高我们使用的Python脚本实现接入数据通路的这部分代码的生成可精准的生成每一个数据项接入数据通路的代码段实现了本次重构工作在测试及上线阶段零Bug。
本篇的内容先简单介绍数据通路的基础功能随后再阐述如何利用Python编写的自动化工具XXXSetting模块作为数据项提供方集成到数据通路中代码自动的生成的实现思路。
01 数据通路技术实现与接入
基于本次配置数据项重构工作的目标和数据通路的复用数据通路的实现目标为可支持不同模块接入如图-1所示与数据通路相关的模块共为两类。 △图-1
1.1 数据项交互模块定义及简介
数据项按照供需关系主要分为两类数据项提供模块和数据项使用模块。
1、数据项提供模块数据的提供方如本文中提到的XXXSetting遵循系统中约定的数据读写协议为系统提供互通的数据项支持。数据项与数据项提供模块是n:1的关系。数据通路支持多个数据项提供模块的接入是 1:n 的关系。
2、数据项使用模块数据的使用方如上篇文章中的XXXLib中的模块基于数据通路提供的能力进行数据的读写调用获取及更新所依赖的数据项的值。数据通路与数据项使用模块是 1:n 的关系。
1.2 数据通路实现及模块简介
数据通路的主体实现思路为提供统一的接口支持不同的数据项提供模块接入在数据通路中管理接入数据项提供模块当数据项使用模块需要读写数据时根据数据通路提供的接口进行数据项的数据同步。主要分为数据项提供模块接口层、数据项提供模块管理和数据项读写服务模块。
1、数据项提供模块接口层约定数据项提供方要实现的数据读写能力只有按照该标准实现的模块才可作为数据的提供模块接入。
2、数据项提供模块管理管理系统中所有数据项提供模块提供注册的接口数据项提供模块可调用注册接入需要在数据通路中管理的数据项。同时在收到数据项读写请求时对模块中所关联的数据项的读写进行分发。
3、数据项读写服务模块提供稳定的数据读写的能力全局可访问根据key查找数据项提供模块并调用数据项提供模块的接口实现数据项的读写。
02 数据提供方接入数据通路的实现
2.1 数据项接入数据通路的主要工作
1、数据提供模块接入数据通路按照数据项提供模块接口层约定实现数据项的读写主要分两步 向数据通路注册可读写的数据项的信息是一个数组数组中存放的是每个数据项的KeyKey的命名规则为数据项提供模块类名_数据项名这部分代码使用Python脚本自动生成。 数据项的读写由数据项提供模块实现读写数的接口根据key匹配数据项之后再对该数据项进行读写 这部分代码也使用Python脚本自动生成。
2、数据项使用模块接入数据通路由原直接调用方式改为通过数据通路间接调用的方式详细实现在下一篇内容介绍敬请关注。
2.2 需要重构的数据项整理
在上一篇《通过Python脚本支持OC代码重构实践一模块调用关系分析》的内容中3.1.2 提取的是变量类型和变量的名称小节中经过预处理后可提取所有数据项的类型及数据项名称。
同时结合上篇3.3.2 数据项的预分析统计输出小节中取数据项被多个组件使用的数据项确定为本次需要重构的数据项。
将这两部分数据进行交集的计算得出来需要重构的数据项类型及数据项名称全集为数据项读写代码生成时使用。下面为数据集的示例。
// 数据项类型 数据项名称;
NSString value1;
NSString value2;
BOOL value3;
...2.3 数据项提供模块的数据项列表生成
数据通路本身不产生数据只作数据读写的桥接。数据项提供模块接入到数据通路时需要知知数据通路支持那些数据项的读写。
具体的实现为通过数据项提供模块接口层的约定告知数据通路由数据通路调用返回数据项提供模块支持的数据项列表数据项列表的数据结构为数组数组中为每个数据项的keykey的生成格式为数据项提供模块类名_数据项名。Python实现的转换代码如下
# 原代码行示例 NSString value1; 参考2.2小节中的代码
matchObj re.match(r(.*)\s(.*);, line, re.M|re.I)
if matchObj:# value matchObj.group(2) -- value1key \ className _ matchObj.group(2) \,\n# key className_value1,\n # key 按OC的写法每一行一个key按NSArray的方式初始化多个key2.4 数据项读取代码生成
注册了可通过数据通路读写的数据项当数据通路需要读写该数据项时数据项提供方按照标准实现数据项的读写。
2.4.1 数据项读取代码示例
数据通路支持基本的数据类型的读取每一种数据类型对应的不同的读取接口数据提供方根据数据项的类型实现不同类型数据读取同一种数据类型中数据提供方根据key返回的对应的数据项值目标生成的OC代码如下
// 数据项是 NSString类型
- (NSString *)stringForKey:(NSString *)key {if ([key isEqual:className_value1]) {return self.value1;}
// 如有多个数据项自动也合到同一个函数if ([key isEqual:className_value2]) {return self.value2;}return nil;
}// 数据项是 BOOL类型
- (BOOL)boolForKey:(NSString *)key {if ([key isEqual:className_value3]) {return self.value3;}return NO;
}
// 其它...2.4.2 数据项读取实现生成
因数据项的类型不同需要使用不同的接口读取故在代码转换时会根据数据项的类型将转换后的代码行分别的存储在不同的数据变量中每个数据变量会在初始化时增加函数头在转换结束后增加函数尾。
函数头示例以数据项为NSString类型为例
# NSString 类型的数据读接口函数头字串由变量保存
funName - (NSString *)stringForKey:(NSString *)key {函数体示例每个数据项均生成对应的代码依次的存储每个数据项的读取
# 原代码行示例 NSString value1; 参考2.2小节中的代码
matchObj re.match(r(.*)\s(.*);, line, re.M|re.I)
if matchObj:funbody if ([key isEqual:\funbody className_ matchObj.group(2) \]) {\nfunbody return self. matchObj.group(2) ;\nfunbody }\n\n# funbody 为转换之后的读取某个数据项的部分代码匹配key之后再返回对应的值增加一些空格及换行代码按规范对齐# if ([key isEqual:className_value1]) {# return self.value1;# }函数尾示例以NSString类型为例所有数据项转换完成之后再增加
funEnd return nil;\n
funEnd }\n\n不同的数据类型依次转换所有数据项转换完成之后依次的组合成为一个文件文件的内容可以直接copy到项目工程中可直接的使用。
2.5 数据项更新
2.5.1 数据项更新代码示例
数据通路支持基本的数据类型的更新每一种数据类型对应的不同的更新接口数据提供方使用根据数据项的类型实现不同类型数据更新同一种数据类型中数据提供方根据key更新的对应的数据项值目标生成的OC代码如下
// 数据项是 NSString类型
- (void)updateString:(NSString *)value forKey:(NSString *)key {if ([key isEqual:className_value1]) {self.value1 value;return;}
// 如有多个数据项自动也合到同一个函数if ([key isEqual:className_value2]) {self.value2 value;return;}
}// 数据项是 BOOL类型
- (void)updateBool:(BOOL)value forKey:(NSString *)key {if ([key isEqual:className_value3]) {self.value3 value;return;}
}// 其它...2.5.2 数据项更新实现生成
因数据项的类型不同需要使用不同的接口更新数据项故在代码转换时会根据数据项的类型将转换后的代码行分别的存储在不同的数据变量中每个数据变量会在初始化时增加函数头在转换结束后增加函数尾。
函数头示例
# NSString 类型的数据读接口函数头字串由变量保存
funName - (void)updateString:(NSString *)value forKey:(NSString *)key {函数体示例每个数据项均生成对应的代码依次的存储每个数据项的读取
# 原代码行示例 NSString value1; 参考2.2小节中的代码
matchObj re.match(r(.*)\s(.*);, line, re.M|re.I)
if matchObj:funbody if ([key isEqual:\funbody className_ matchObj.group(2) \]) {\nfunbody self. matchObj.group(2) value;\nfunbody return;\nfunbody }\n\n# funbody 为转换之后的更新某个数据项的部分代码匹配key之后再返回对应的值增加一些空格及换行代码按规范对齐# if ([key isEqual:className_value1]) {# self.value1 value;# return;# }函数尾示例所有数据项转换完成之后再增加
funEnd }\n\n03 小结
本篇的内容基于上一篇内容的分析结论将被多个组件使用的数据项接入到数据通路的代码使用Python脚本自动生成的实践。
因涉及到的数据项较多需要在所有的数据项中选出需要重构的数据项生成数据项key列表并跟据数据项的类型接入到不同类型的读写接口中。使用人工书写代码的方式很难保证数据项接入到数据通路过程的质量同时也很难验证数据项迁移的完整性。
而使用Python脚本实现工具支持数据项接入数据通路的代码生成可以自动的、精准的生成每一个数据项接入数据通路的代码可减少研发及测试人力的投入间接的提升了研发效率。
下一篇我们将介绍如何通过Python脚本支持数据项使用模块接入数据通路时的适配感兴趣的同学可以持续关注。 欢迎加入百度搜索大前端团队持续招聘iOS/Android/Web前端研发工程师 简历欢迎投递至joinefebaidu.com ——END——
推荐阅读
对话InfoQ聊聊百度开源高性能检索引擎 Puck
浅谈搜索展现层场景化技术-tanGo实践
初识搜索百度搜索产品经理的第一课
智能问答技术在百度搜索中的应用
通过Python脚本支持OC代码重构实践一模块调用关系分析