数学建模社区-数学中国
标题:
代码洁癖系列(五):外在的格式美
[打印本页]
作者:
杨利霞
时间:
2019-3-23 15:52
标题:
代码洁癖系列(五):外在的格式美
代码洁癖系列(五):外在的格式美
1 X& e7 h. `3 X+ J! ]: A0 z) q
# [9 ^9 y' u5 l( H
我们在阅读一些优秀项目的源码时,一定会感叹他们代码的整洁和一致性。而作为第一印象,代码格式的整齐是让人能够继续阅读下去的动力。今天我们分别从垂直格式和横向格式两个方面来讨论代码的格式。修正格式的方法有:间隔、靠近和调整顺序。
2 C( O- a! _* l, C& \9 G6 F2 o
垂直格式
% O: Q2 L' A( g
: |6 p" L; F6 q/ g. n: a. B
在垂直格式方面,我们要向报纸的排版学习。
5 S/ \ j" D ^5 S/ ~% r' a5 d
. F% j- C# _) I7 A2 E, d, J6 |; O
Z$ E) k* m& u6 C
0 h/ O& o3 s+ U" x) _5 z
首先有一个标题告诉你这栏新闻要讲什么,好让你知道是否要继续阅读下去。对应到代码中就是类的名字,我们要力求只通过名字就可以知道这个类要描述什么事情;然后,代码的第一段往往都交代了整个故事的概要,类似于代码中的接口,我们往往通过接口了解类中有哪些函数,每个函数都是干什么的。了解了这些之后,才会去读详细的内容。
: F* |0 G! U# ?
' N( X3 ], M- p# o- Z0 O% R
newspaper code
Z6 L: ^& y1 i2 D: | v/ |
标题 类名
" M' U8 M/ @- D- O* j; k
第一段 接口
7 N8 a: w x2 B/ `' A" d; R
内容 方法体
) I+ G1 [' G/ c% V/ ]- `- N
此外,还需要注意的就是报纸的排版、段落和段落之间用空行做间隔。写代码也可以用同样的方式,例如,我们习惯于在包声明、导入声明和每个函数之间用空白行来分隔。我们直接拿代码来解释。
+ L4 J% `- G) c4 U5 {
" z3 p/ t3 n; d
package com.thoughtworks.selenium;
6 _# b& K" m% x& j: D
import org.testng.ITestContext;
K0 L4 c7 ~1 h, i
import org.testng.ITestResult;
( X. w. g$ _! A2 D: d
import org.testng.Reporter;
: v3 z. A) J4 T. Z% N% s! ]- J9 R& H! E
import org.testng.internal.IResultListener;
5 X2 e; H# g5 N4 @$ R1 m7 m
9 ~; o4 b9 Y" c, l
import java.io.File;
9 v2 w- N4 ]$ E
Q: ]2 p5 x& c9 t
public class ScreenshotListener implements IResultListener {
7 l8 v) } ~+ E8 h
/ J* u* R( G( h
File outputDirectory;
6 q$ Q ^3 j$ c: X+ C/ M `, Y& v
Selenium selenium;
/ Y Q1 d1 o- [/ B
# L2 a# S. n/ ?- f
public ScreenshotListener(File outputDirectory, Selenium selenium) {
! F3 y% j7 [! V/ J& f2 Y
this.outputDirectory = outputDirectory;
8 f( O3 v7 p9 U$ c1 F% o
this.selenium = selenium;
" i& Y* R3 u0 h# {. u: o: a# A: z
}
$ w' t4 q& N2 O/ u0 n
! [) N$ J4 p% t1 }
public void onTestFailure(ITestResult result) {
1 T5 k& l% S) e, I$ g& I
Reporter.setCurrentTestResult(result);
D4 B: f6 }# ^' [1 z: K8 ^
- |3 n6 o! F. ]
try {
S6 ]+ }; K/ |! O+ ?9 S
outputDirectory.mkdirs();
. V7 ^$ ?( x A1 Z$ f
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
1 K+ J- ^( v2 p
outFile.delete();
7 C$ D* ]0 p: p9 k: A
selenium.captureScreenshot(outFile.getAbsolutePath());
0 w% C; _8 L" C- A+ y
Reporter.log("<a href='" +
* p N, s+ a1 s3 j
outFile.getName() +
# C/ G3 |% r/ Y" t4 f: C
"'>screenshot</a>");
* i6 h, Z# U+ V" R- B
} catch (Exception e) {
4 G$ k" y/ w9 C2 m' f$ ~* _4 _" E
e.printStackTrace();
2 |6 x R: v) \' \9 N0 O
Reporter.log("Couldn't create screenshot");
! d) O% v% E* b$ |, F- s
Reporter.log(e.getMessage());
# m6 r. G6 F3 B% i+ P7 B; T# S
}
. F3 L$ y- N: F+ {- g
5 t( H3 q3 u0 f; {2 y8 ^+ M
Reporter.setCurrentTestResult(null);
; |5 {& y# F k1 B, h2 g, z
}
5 g( T, |* ^8 y! w/ P
}
1 X; I6 I E5 i d% q
0 g" j9 f, c7 N' ?0 L# A1 H O
package com.thoughtworks.selenium;
# [+ A l7 O' ^4 e) B
import org.testng.ITestContext;
5 I I2 ]1 B% x2 b9 i6 z% x- _
import org.testng.ITestResult;
& {- {4 z) ]. t( j" }2 }" G" S
import org.testng.Reporter;
; O% O# A0 V% M7 {# D S
import org.testng.internal.IResultListener;
# x* w r! [! k$ L
import java.io.File;
% j4 d9 N0 ^, i: F5 J! ]( n9 W
public class ScreenshotListener implements IResultListener {
- k, k _; j0 m J8 u
File outputDirectory;
. M! Z8 k6 o5 L7 j; S
Selenium selenium;
5 I- \% V3 |- D7 G/ Z
public ScreenshotListener(File outputDirectory, Selenium selenium) {
% O2 C& V2 o H: }
this.outputDirectory = outputDirectory;
; |2 Q, M5 [- Y; W$ ^
this.selenium = selenium;
2 N* S9 N" f# l
}
" R H! {- K7 Y9 A7 d0 `6 @
public void onTestFailure(ITestResult result) {
6 W3 [. A/ W& m4 d
Reporter.setCurrentTestResult(result);
* e; c+ s0 e" o
try {
0 |$ S3 I% o7 e9 o& ]
outputDirectory.mkdirs();
3 A& x) t! {; G$ Z" F- b
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
, Z9 a- K6 Z) g y3 P3 y8 X( D
outFile.delete();
" P5 n/ K) d1 `$ U2 A: L7 e' P* f
selenium.captureScreenshot(outFile.getAbsolutePath());
" D' Q# b, M- Z- W5 S3 B
Reporter.log("<a href='" +
- H1 I2 D& P5 b o. P
outFile.getName() +
- l# q4 L* u- ~2 i4 ]
"'>screenshot</a>");
* e# x7 y: V0 X0 v0 G/ T% z! n2 j
} catch (Exception e) {
% O7 s8 k6 {; v/ L: m \
e.printStackTrace();
$ z! b: Q; T5 j. J3 W6 X' _
Reporter.log("Couldn't create screenshot");
4 @8 R3 Y/ \# I8 g7 n
Reporter.log(e.getMessage());
. t+ @8 X& f* Y; y+ M, e- O' o: s
}
7 @9 t0 H3 z( v2 W8 Y" s$ p
Reporter.setCurrentTestResult(null);
- Z& l+ G( ]# \% Y; Q
}
% K' D B% \5 |4 u E% d y
}
" K% P( W! H4 u+ u
是不是适当增加空白行就提高了代码的可读性呢,这里说的是适当增加空白行,并不代表随意增加。事实上,如果增加一些无意义的空白行反而会使代码的可读性变差。
9 v8 ^6 M8 t: T$ q* G' ?; ]
) j# [+ k6 D- w
我们习惯于使有关联的代码彼此靠近,无明显关联的代码相互分隔。因此我们不但需要使用空白行间隔代码,还要调整代码位置,把有关联的代码放在一起,通常我们把被调用的函数放在调用函数的下面。这样别人在读我们的代码的时候再也不用经历来回“跳跃”的痛苦了。
$ t4 F- I1 b" t# A6 _
8 s/ H0 e5 c' D t9 n! p
最后,我们通常把实体变量定义在类的顶部,这个只是我们Java程序员的习惯操作,如果突然在类的中间位置出现一个变量声明会让人觉得很奇怪。如果你想说,定义在中间是不想让定义位置和调用位置离太远,那么只能说明你的类定义出现了问题。建议你看一下旧文代码洁癖系列(三):整洁的类和函数。
7 q, k7 T2 u* v/ F% X' H
3 ^ }& ~; Z3 J4 Q- u
横向格式
4 H1 B$ e- O8 L4 _
r# h0 K, V; k$ @& s
介绍完垂直格式,紧接着自然要来介绍一下它的兄弟,横向格式。或许你会问为什么不叫水平格式,我的回答是:也可以叫水平格式,只要你喜欢。横向格式也是需要间隔和靠近的,这里的间隔主要是为了起到强调的效果。举个例子。
3 P- }4 H1 q9 o2 z. Z& `' O
, H- M \7 U1 {" `0 @
int lineSize = line.length();
& S9 M1 |/ ~) y" r4 @! q
1
1 Z4 y2 P* T/ h T# j
这里等号两边的空格分别是为了强调左右两边的元素。横向格式另一个比较重要的元素就是缩进,Java程序对缩进没有强制性要求,而Python程序对缩进的要求非常严格,稍有不慎,执行的结果就会不同。但是Java程序员也要注意缩进,因为我们的代码是层级关系,而缩进可以帮我们快速理清层级关系。
1 n! s% a1 J" l& P3 ~' ?
& K* e- r* T0 Q0 d9 Y
最后,横向代码格式对每行代码长度是有要求的,如果代码过长,那么在阅读的时候就需要左右滑动,而这个操作其实是不受人喜欢的。虽然现在代码编辑器可显示的长度变大了,但我们还是习惯每行代码最多100个字符。
/ |& J4 y* z: Z7 P/ q
6 g e- c5 f. r. u, m
团队的规则
. h" D9 H2 } {
4 D5 t" c% s F2 E: U
每一个优秀的团队都已一套属于自己的代码格式要求,有些是特定的,有些是使用公共的。我们team所用的代码规范就是Google的代码规范,阿里的代码规范也是比较被大家认可的。这里给大家一个小福利,在我的公众号后台回复【代码规范】,就可以获得一份阿里的Java开发手册。
* L, ]2 T: s- \# g$ j8 G ?
---------------------
. S% c$ b6 B5 F4 m* U$ [
) w( ]3 S- J# h% I" a
9 V1 T1 {! o; s# O+ ~( V
8 ` n, e& ?0 F. W% L+ k
3 L! x0 ?/ V3 f8 }) Q$ l
8 Q$ k ~. C. v" D$ _6 ?( ~2 m
' N! Z+ O0 `$ |# {. h
* v6 d1 G% j5 f ~& C f% t
. u$ B& {0 \$ H! I: T# d6 y# G
c6 l6 f6 J! h& N" `3 U! d* K
* m$ D7 _' a" U
5 Y" L4 u# t# `4 G5 |- g# h4 @
, }( i0 q4 S* N) b+ J. ^
7 G6 T2 N2 L& W: S1 G' k
- W/ b2 y8 B" @. R8 g2 N
& G' s; N) r$ |) D. L6 Y8 k2 A
9 ?0 x$ l- ?1 `2 Z7 P& r
4 ]. H E. J0 |( ?
5 B; ]8 g; Q; W* N- v2 ]' Y
5 C+ j; }0 v/ {$ A# w5 H4 \
$ P, R* x$ L6 a0 J% r! G
& r* Z# ]9 K- a
/ f9 p2 O! d1 w
; i8 q3 @- B7 u: R& I5 }0 K
# i8 s0 }: P) o
( A6 n ~& y& K, `
' G5 P2 B% e$ O, Y7 ]$ q7 s/ A
K0 Y7 E( E6 G
16种常用的数据分析方法汇总.docx
2019-3-25 17:29 上传
点击文件名下载附件
下载积分: 体力 -2 点
20.53 KB, 下载次数: 1, 下载积分: 体力 -2 点
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5