如何写好代码-抽取流程

之前写了一段解析网页的代码,现在回头重构,发现烂得不行。这里选取一段关于流程的做个分析改进。

原始代码

这段代码的目的是解析页面的HTML,获取数据后,生成一个Person数据实例,然后对其进行数据筛选,最终将不符合条件的页面元素隐藏掉,给符合条件的页面元素打上文字标记。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* 解析单个学生的信息
* @param {*} $li 学生对应的jQuery对象,是一个li元素
*/
function parseSingleStudent($li) {
if ($li.hasClass('ths_parsed')) {
return false;
}
let student = new Person();

// 沟通信息
let communication = $li.find('.sider-op').find('.btn-greet').html()

// 已经沟通过了
if ('undefined' === typeof communication) {
student.communicated = true;
} else if ('' !== communication && communication.indexOf('打招呼') < 0) {
student.communicated = true;
}

// 只找第一级子元素,应该用children,而不是find
let $cards = $li.find('.card-inner').eq(0).children('div');
if (0 === $cards.length) {
return false;
}
student.name = $cards.eq(1).find('.name').html().replace(/<(.*)>/, '').trim();
student.gender = $cards.eq(0).find('.iboss-icon_women').length > 0 ? 'female' : 'male';
let $info = $cards.eq(1).find('.info-labels').eq(0).find('.label-text');
student.age = $info.eq(0).html().replace('岁', '')
student.highestDegree = $info.eq(2).html();
student.description = $cards.eq(1).find('.advantage-new').html().trim();

// 经验区域
let $experienceUls = $cards.eq(2).children('ul');

// 学习经历
// 专升本
let studyHtml = $experienceUls.eq(1).html();
if ('undefined' !== typeof studyHtml && (studyHtml.indexOf('大专') >= 0 || studyHtml.indexOf('中专') >= 0)) {
student.isCollegeToUniversity = true;
}

let $studyExperienceUl = $experienceUls.eq(1).find('li').eq(0).find('span')
getStudyInformation($studyExperienceUl)

function getStudyInformation($studyExperienceUl) {
let latestStudyYears = $studyExperienceUl.eq(0).html()
if ('undefined' !== typeof latestStudyYears) {
student.graduateTime = latestStudyYears.split('-')[1];
}

let universityString = $studyExperienceUl.eq(1).html()
if ('undefined' !== typeof universityString) {
let universityInfo = universityString.trim().split('\n')
student.university = universityInfo[0];

if ('undefined' !== typeof universityInfo[2]) {
student.major = universityInfo[2].split('&nbsp;·&nbsp;')[1];
}
}
}

let tags = [];
// log(student.toString());
let checkTags = verify(student, option.filter);
if (!checkTags || isIgnored(student, state.ignoreUsers)) {
$li.css("display", "none");
} else {
// 抽离出来,单独弄一个渲染方法
$li.css("background-color", "#e0c7c7");
tags = tags.concat(checkTags)
tags.length && sign($li, tags);

addDonotShowButton($li, student);

// 弹窗通知
notify(`找到一个符合条件的简历:${tags.join(', ')}`);
}

$li.addClass('ths_parsed');
}

这段代码前面部分没有太大问题,问题主要集中在后面,从let tags = []开始,后面的内容,就比较乱了,应该抽取出来才对。这段代码的流程其实应该是:解析html->生成Person实例对象->检查Person实例的数据->根据检查结果做页面上的差异化渲染。

程序设计方法

还是可以参考可视化组件的编写方法,形成套路。

至少要包括:

流程类

配置类/defaultOption,同样的,配置也分为数据筛选配置+页面渲染的样式配置

视图操作类/函数集合

数据结构/Model

数据处理类/函数集合

事件类

总结

先写出流程类和流程方法

理清楚流程,才能帮助你更好的做程序设计,知道有哪些类和方法、哪些该独立、具体要做哪些事情。

高内聚,低耦合

函数式编程,所有依赖都通过参数传入,这样你的函数才能独立,才方便复用和迁移。