Skip to content

Commit bf41b39

Browse files
committed
Add refactor project
1 parent 8d10078 commit bf41b39

File tree

1 file changed

+154
-1
lines changed

1 file changed

+154
-1
lines changed

chapters/11-refactor-project.md

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,154 @@
1-
#重构
1+
#重构
2+
3+
或许你应该知道了,重构是怎样的,你也知道重构能带来什么。在我刚开始学重构和设计模式的时候,我需要去找一些好的示例,以便于我更好的学习。有时候不得不创造一些更好的场景,来实现这些功能。
4+
5+
有一天,我发现当我需要我一次又一次地重复讲述某些内容,于是我就计划着把这些应该掌握的技能放到Github上,也就有了[Artisan Stack](https://github.com/artisanstack) 计划。
6+
7+
每个程序员都不可避免地是一个Coder,一个没有掌握好技能的Coder,算不上是手工艺人,但是是手工人。
8+
9+
艺,需要有创造性的方法。
10+
11+
#[前端技能训练: 重构一](http://www.phodal.com/blog/frontend-improve-refactor-javascript-code/)
12+
13+
##为什么重构?
14+
15+
> 为了更好的代码。
16+
17+
在经历了一年多的工作之后,我平时的主要工作就是修Bug。刚开始的时候觉得无聊,后来才发现修Bug需要更好的技术。有时候你可能要面对着一坨一坨的代码,有时候你可能要花几天的时间去阅读代码。而,你重写那几十代码可能只会花上你不到一天的时间。但是如果你没办法理解当时为什么这么做,你的修改只会带来更多的bug。修Bug,更多的是维护代码。还是前人总结的那句话对:
18+
19+
> 写代码容易,读代码难。
20+
21+
假设我们写这些代码只要半天,而别人读起来要一天。为什么不试着用一天的时候去写这些代码,让别人花半天或者更少的时间来理解。
22+
23+
如果你的代码已经上线,虽然是一坨坨的。但是不要轻易尝试,``没有测试的重构``
24+
25+
从前端开始的原因在于,写得一坨坨且最不容易测试的代码都在前端。
26+
27+
让我们来看看我们的第一个训练,相当有挑战性。
28+
29+
##重构uMarkdown
30+
31+
代码及setup请见github: [js-refactor](https://github.com/artisanstack/js-refactor)
32+
33+
###代码说明
34+
35+
``uMarkdown``是一个用于将Markdown转化为HTML的库。代码看上去就像一个很典型的过程代码:
36+
37+
```javascript
38+
/* code */
39+
while ((stra = micromarkdown.regexobject.code.exec(str)) !== null) {
40+
str = str.replace(stra[0], '<code>\n' + micromarkdown.htmlEncode(stra[1]).replace(/\n/gm, '<br/>').replace(/\ /gm, '&nbsp;') + '</code>\n');
41+
}
42+
43+
/* headlines */
44+
while ((stra = micromarkdown.regexobject.headline.exec(str)) !== null) {
45+
count = stra[1].length;
46+
str = str.replace(stra[0], '<h' + count + '>' + stra[2] + '</h' + count + '>' + '\n');
47+
}
48+
49+
/* mail */
50+
while ((stra = micromarkdown.regexobject.mail.exec(str)) !== null) {
51+
str = str.replace(stra[0], '<a href="mailto:' + stra[1] + '">' + stra[1] + '</a>');
52+
}
53+
```
54+
55+
选这个做重构的开始,不仅仅是因为之前在写[EchoesWorks](https://github.com/phodal/echoesworks)的时候进行了很多的重构。而且它更适合于,``重构到设计模式``的理论。让我们在重构完之后,给作者进行pull request吧。
56+
57+
Markdown的解析过程,有点类似于``Pipe and Filters``模式(架构模式)。
58+
59+
Filter即我们在代码中看到的正规表达式集:
60+
61+
```javascript
62+
regexobject: {
63+
headline: /^(\#{1,6})([^\#\n]+)$/m,
64+
code: /\s\`\`\`\n?([^`]+)\`\`\`/g
65+
```
66+
67+
他会匹配对应的Markdown类型,随后进行替换和处理。而``str```,就是管理口的输入和输出。
68+
69+
接着,我们就可以对其进行简单的重构。
70+
71+
###重构
72+
73+
(ps: 推荐用WebStrom来做重构,自带重构功能)
74+
75+
作为一个示例,我们先提出codeHandler方法,即将上面的
76+
77+
```javascript
78+
/* code */
79+
while ((stra = micromarkdown.regexobject.code.exec(str)) !== null) {
80+
str = str.replace(stra[0], '<code>\n' + micromarkdown.htmlEncode(stra[1]).replace(/\n/gm, '<br/>').replace(/\ /gm, '&nbsp;') + '</code>\n');
81+
}
82+
```
83+
84+
提取方法成
85+
86+
```javascript
87+
codeFilter: function (str, stra) {
88+
return str.replace(stra[0], '<code>\n' + micromarkdown.htmlEncode(stra[1]).replace(/\n/gm, '<br/>').replace(/\ /gm, '&nbsp;') + '</code>\n');
89+
},
90+
```
91+
92+
while语句就成了
93+
94+
```javascript
95+
while ((stra = regexobject.code.exec(str)) !== null) {
96+
str = this.codeFilter(str, stra);
97+
}
98+
```
99+
100+
然后,运行所有的测试。
101+
102+
```
103+
grunt test
104+
```
105+
106+
同理我们就可以``mail````headline``等方法进行重构。接着就会变成类似于下面的代码,
107+
108+
```javascript
109+
/* code */
110+
while ((execStr = regExpObject.code.exec(str)) !== null) {
111+
str = codeHandler(str, execStr);
112+
}
113+
114+
/* headlines */
115+
while ((execStr = regExpObject.headline.exec(str)) !== null) {
116+
str = headlineHandler(str, execStr);
117+
}
118+
119+
/* lists */
120+
while ((execStr = regExpObject.lists.exec(str)) !== null) {
121+
str = listHandler(str, execStr);
122+
}
123+
124+
/* tables */
125+
while ((execStr = regExpObject.tables.exec(str)) !== null) {
126+
str = tableHandler(str, execStr, strict);
127+
}
128+
```
129+
130+
然后你也看到了,上面有一堆重复的代码,接着让我们用JavaScript的``奇技浮巧``,即apply方法,把上面的重复代码变成。
131+
132+
```javascript
133+
['code', 'headline', 'lists', 'tables', 'links', 'mail', 'url', 'smlinks', 'hr'].forEach(function (type) {
134+
while ((stra = regexobject[type].exec(str)) !== null) {
135+
str = that[(type + 'Handler')].apply(that, [stra, str, strict]);
136+
}
137+
});
138+
```
139+
140+
进行测试,blabla,都是过的。
141+
142+
```javascript
143+
Markdown
144+
✓ should parse h1~h3
145+
✓ should parse link
146+
✓ should special link
147+
✓ should parse font style
148+
✓ should parse code
149+
✓ should parse ul list
150+
✓ should parse ul table
151+
✓ should return correctly class name
152+
```
153+
154+
快来试试吧, [https://github.com/artisanstack/js-refactor](https://github.com/artisanstack/js-refactor)

0 commit comments

Comments
 (0)