数学建模社区-数学中国
标题:
代码洁癖系列(五):外在的格式美
[打印本页]
作者:
杨利霞
时间:
2019-3-23 15:52
标题:
代码洁癖系列(五):外在的格式美
代码洁癖系列(五):外在的格式美
3 b3 s0 N! d/ }( n- {1 S1 c
( Y y! y' R( Z
我们在阅读一些优秀项目的源码时,一定会感叹他们代码的整洁和一致性。而作为第一印象,代码格式的整齐是让人能够继续阅读下去的动力。今天我们分别从垂直格式和横向格式两个方面来讨论代码的格式。修正格式的方法有:间隔、靠近和调整顺序。
J* S9 e1 ~" Y, S% g# r: ~! z
垂直格式
6 f& D) x& T1 d! W3 w r( x C x: |
. ]% \" o. C. k8 O2 a6 ?
在垂直格式方面,我们要向报纸的排版学习。
B5 }6 x# A! ~, V" Q
$ k d9 P( `: K- Y+ u- M3 S2 O
' [ A$ h5 U0 F) `% G( N# a8 C
x1 w# \% A/ v$ C( `
首先有一个标题告诉你这栏新闻要讲什么,好让你知道是否要继续阅读下去。对应到代码中就是类的名字,我们要力求只通过名字就可以知道这个类要描述什么事情;然后,代码的第一段往往都交代了整个故事的概要,类似于代码中的接口,我们往往通过接口了解类中有哪些函数,每个函数都是干什么的。了解了这些之后,才会去读详细的内容。
' I5 Y( S5 ]' r& y
: m: {- L8 m$ ~' D- v
newspaper code
- |$ S' I% I2 [/ N
标题 类名
2 G8 ?% R9 m2 h5 p
第一段 接口
5 N1 Q( O+ _& ~5 Y4 [
内容 方法体
' ?$ D& `, w! z" M# w9 y, y/ k
此外,还需要注意的就是报纸的排版、段落和段落之间用空行做间隔。写代码也可以用同样的方式,例如,我们习惯于在包声明、导入声明和每个函数之间用空白行来分隔。我们直接拿代码来解释。
) S$ ?4 u# S& R! a
" ?7 h8 h" {8 E+ t2 M+ S) I" @
package com.thoughtworks.selenium;
* s+ v& ?4 y. u- j
import org.testng.ITestContext;
3 p, u7 H: F. t/ ]+ }/ R
import org.testng.ITestResult;
; G! M- q% y! T9 I4 e
import org.testng.Reporter;
- q. n& ~: \4 d
import org.testng.internal.IResultListener;
; }3 e; \9 p& n1 R
$ u* K: z, o u6 b- I
import java.io.File;
' Q0 l) o$ l% A0 q; t8 O
# Z0 J5 u, _$ u; i. S. a
public class ScreenshotListener implements IResultListener {
9 N' @4 d7 @" e; ]
! W/ c: L! i8 |/ J0 ]2 g. Q
File outputDirectory;
. n7 i8 d4 C& }8 |$ T$ b4 |
Selenium selenium;
) L' F& H- p/ U! |/ A
u$ |; R9 q' ]% ]6 U: ]
public ScreenshotListener(File outputDirectory, Selenium selenium) {
& T. r n: a- w4 U( C" ?' y
this.outputDirectory = outputDirectory;
; `8 k* j4 A# z" m" t d& D
this.selenium = selenium;
. Y7 n% q/ R4 C- ]
}
' M4 l8 j) E- ]7 a/ ]' w s
/ u4 g$ w, t6 } U* |3 n
public void onTestFailure(ITestResult result) {
0 q- A* u1 C' y
Reporter.setCurrentTestResult(result);
: S2 f9 _9 G/ `
3 z) J; N% q- Y) n8 b! C$ x
try {
. h8 x% W4 M/ r
outputDirectory.mkdirs();
. D& g/ d3 Z: R% T' F
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
; ?+ {; E4 D+ @* H; c0 t
outFile.delete();
) k& z4 |& h; G1 D2 C) ^) Q4 ^
selenium.captureScreenshot(outFile.getAbsolutePath());
5 ^) t+ j4 S: ]% o) a' p
Reporter.log("<a href='" +
1 k% M' o& e+ e" N9 d
outFile.getName() +
. x6 @8 G" E5 }) Q: C' I3 ]
"'>screenshot</a>");
& P' _8 Q# a7 \& n
} catch (Exception e) {
$ O" O3 {2 s9 U$ }! e& @; X
e.printStackTrace();
1 n% d. }9 V7 x, C& v" U: i
Reporter.log("Couldn't create screenshot");
. f `. [7 _2 b5 x, D! G
Reporter.log(e.getMessage());
. d; O `, Q: _' S$ R2 E0 D7 B
}
. d; R2 _ a- ~! z+ h
. [/ E& C; _3 i) N- P
Reporter.setCurrentTestResult(null);
7 n7 h$ T' V! M4 j3 i# j
}
E6 i2 C& s0 f
}
0 ~. v( e, S& B' f0 v
9 |2 _3 R; @6 F
package com.thoughtworks.selenium;
+ T. {! g* S o" C U
import org.testng.ITestContext;
* Z/ T. q2 J( a1 T3 ?( `
import org.testng.ITestResult;
2 K C, A8 v j- z; P
import org.testng.Reporter;
" s% x$ |7 Q- J4 j* w2 V k
import org.testng.internal.IResultListener;
+ Z/ Q5 `0 }$ O" S
import java.io.File;
: e. g1 }4 C/ l) K
public class ScreenshotListener implements IResultListener {
9 k8 k& C" K$ A; J. _) z
File outputDirectory;
0 s& W/ @9 O1 g
Selenium selenium;
* I* a8 P3 A0 o& i9 ]" x
public ScreenshotListener(File outputDirectory, Selenium selenium) {
, E1 {: D2 L2 a3 }+ X4 q0 W
this.outputDirectory = outputDirectory;
. e: N* r- M" q) Y2 T
this.selenium = selenium;
- P3 h, n9 _( _/ R! s' _. p
}
; c/ d+ _% T# M& ]% o* s; l
public void onTestFailure(ITestResult result) {
$ K- q6 s" _: ~- ^4 f* x7 H
Reporter.setCurrentTestResult(result);
( X- Z6 a6 |% Q; e4 g$ j0 n
try {
) G0 ?) Y5 @1 t1 [. z
outputDirectory.mkdirs();
) m8 B! p# d5 @2 M, K% e6 ~
File outFile = File.createTempFile("TEST-" + result.getName(), ".png", outputDirectory);
5 Q _$ P& V6 ~& t& E
outFile.delete();
* d0 F2 A+ r3 @3 Z( x
selenium.captureScreenshot(outFile.getAbsolutePath());
- j, E) g* T6 A3 e
Reporter.log("<a href='" +
' m- a7 F! I6 Y, A3 K8 |
outFile.getName() +
% ^* V! p# {# P! f% O0 v
"'>screenshot</a>");
% z6 C0 v' w4 a2 g5 W/ q, ]' E% {
} catch (Exception e) {
" E2 b1 q- a! `# D5 p
e.printStackTrace();
7 `, y1 i. M- k& g+ Y2 x' j3 @
Reporter.log("Couldn't create screenshot");
2 P7 `# [3 b; Q, s, v. Y
Reporter.log(e.getMessage());
9 ~' E4 Q& w$ C3 E3 X) }9 }
}
e8 D8 y" F W) I
Reporter.setCurrentTestResult(null);
6 v# p4 U8 |6 }+ v5 t. @
}
+ Z% \( F7 R7 |! J* `
}
5 D1 g+ D; H: ]1 g" ^' E' t
是不是适当增加空白行就提高了代码的可读性呢,这里说的是适当增加空白行,并不代表随意增加。事实上,如果增加一些无意义的空白行反而会使代码的可读性变差。
) a. n8 L4 f2 |8 @0 K, _
4 b q" s e# d2 v
我们习惯于使有关联的代码彼此靠近,无明显关联的代码相互分隔。因此我们不但需要使用空白行间隔代码,还要调整代码位置,把有关联的代码放在一起,通常我们把被调用的函数放在调用函数的下面。这样别人在读我们的代码的时候再也不用经历来回“跳跃”的痛苦了。
4 S) |8 ~: D" l8 L( m" {" B" ?
, b) _6 z2 F; K2 Q: v
最后,我们通常把实体变量定义在类的顶部,这个只是我们Java程序员的习惯操作,如果突然在类的中间位置出现一个变量声明会让人觉得很奇怪。如果你想说,定义在中间是不想让定义位置和调用位置离太远,那么只能说明你的类定义出现了问题。建议你看一下旧文代码洁癖系列(三):整洁的类和函数。
, s8 G4 ]& O' d5 D7 r
9 b; a! N% O8 A+ E, I2 m, ~3 m8 @
横向格式
) N! z3 |9 O% O. t8 ^
# x0 W& p9 a( q/ }
介绍完垂直格式,紧接着自然要来介绍一下它的兄弟,横向格式。或许你会问为什么不叫水平格式,我的回答是:也可以叫水平格式,只要你喜欢。横向格式也是需要间隔和靠近的,这里的间隔主要是为了起到强调的效果。举个例子。
" h7 k* ?5 v" S
7 q& n. m G& f1 s. Z1 z
int lineSize = line.length();
" x, z& @ a' w/ u
1
6 y% a' C$ V! i
这里等号两边的空格分别是为了强调左右两边的元素。横向格式另一个比较重要的元素就是缩进,Java程序对缩进没有强制性要求,而Python程序对缩进的要求非常严格,稍有不慎,执行的结果就会不同。但是Java程序员也要注意缩进,因为我们的代码是层级关系,而缩进可以帮我们快速理清层级关系。
- {2 u0 k! w2 e9 x% S
1 M/ [! H3 k* {6 n
最后,横向代码格式对每行代码长度是有要求的,如果代码过长,那么在阅读的时候就需要左右滑动,而这个操作其实是不受人喜欢的。虽然现在代码编辑器可显示的长度变大了,但我们还是习惯每行代码最多100个字符。
% W+ Z4 S" h( e* X$ G( h
; Y- b9 q& x# J; A+ G
团队的规则
1 y" l, J/ H% t: Y- c
: t5 Z" |; @/ S, x, c. C
每一个优秀的团队都已一套属于自己的代码格式要求,有些是特定的,有些是使用公共的。我们team所用的代码规范就是Google的代码规范,阿里的代码规范也是比较被大家认可的。这里给大家一个小福利,在我的公众号后台回复【代码规范】,就可以获得一份阿里的Java开发手册。
* k" m. S# J3 q0 }% @7 Y
---------------------
1 a) }; V! {6 x8 q& k! U
# I2 W- H8 A+ J4 @, |
$ b' ]! D/ Q% X* N& `' t# ^
3 j5 s. Q- O1 D& A1 Q
# t: W+ r0 j7 N' i+ g
9 j, Q9 u' G8 G& Q1 }0 o
5 X4 @# S/ e/ B, ^* f
+ W# m( C6 m) z; Z5 I5 ]% S G
d7 P. K" N4 R1 A3 g( ~: Y# V
2 |& m. ?0 [3 J9 U5 b. {
! e; ~( F" H7 e
- p) }: w( | t) [( Y0 J
2 v; F/ H; K* l. g5 t% f" m
7 G$ i6 r0 J$ V8 o
% u/ B6 x- j7 j! ]0 B; U
/ X% M6 h+ ]/ y1 B1 a. Z' Z$ Q
$ x/ F# c8 r1 k" D& g
! R4 p i8 }/ y h: j' k) w& I. F
6 \; c p& y% w6 o! r( I
6 F% l# v+ J/ c. z
' T" u A7 s) o$ S& `
$ F+ s/ T7 |4 S0 w) j3 T, R4 m$ Q t
$ z" X n3 |0 A3 s+ @! s
* l* ]: D/ {& T& S" a( j! e
( A/ d+ e/ s( x' L S, ^
" p0 i, U- y: W( J
; D5 ^4 ^& U! d! L+ \- Y- w- _
% n& u9 r* h" ~5 ~" t3 a
16种常用的数据分析方法汇总.docx
2019-3-25 17:29 上传
点击文件名下载附件
下载积分: 体力 -2 点
20.53 KB, 下载次数: 1, 下载积分: 体力 -2 点
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5