数学建模社区-数学中国

标题: 10步让你成为更优秀的程序员 [打印本页]

作者: shutup    时间: 2013-1-2 11:08
标题: 10步让你成为更优秀的程序员
+ P: v  [" q% v8 {
作者: Paul Firth  来源: 外刊IT评论  $ Y6 }- \5 q4 x3 @7 ^

8 X6 ~) @5 l  d  T! X  英文原文:10 steps to becoming a better programmer
% C$ f; r  H2 P: F  这篇文章要介绍的,是我作为专业程序员这些年来学到的能真正提高我的代码质量和整体工作效率的 10 件事情。; s! H# [" a. S7 y& |4 D! Q& z
  1. 永远不要复制代码- J9 o% Z: C: D+ o# d
  不惜任何代价避免重复的代码。如果一个常用的代码片段出现在了程序中的几个不同地方,重构它,把它放到一个自己的函数里。重复的代码会导致你的同事在读你的代码时产生困惑。而重复的代码如果在一个地方修改,在另外一个地方忘记修改,就会产生到处是 bug,它还会使你的代码体积变得臃肿。现代的编程语言提供了很好的方法来解决这些问题,例如,下面这个问题在以前很难解决,而如今使用 lambda 却很好实现:
+ A, l2 U- ?2 d' R* i+ h5 s/// <summary>. J: c( s$ f- y- }
/// 一些函数含有部分重复代码
( k; m4 G# C5 a/ b" N/// </summary>
- b: ~9 v4 C3 H5 R- nvoid OriginalA()' f9 F; K( V; B# u& A
{
4 D+ i  q. J# x6 P4 l  a    DoThingsA();
' L3 v% K5 \+ c! M  ~* y8 C; J    // unique code( D9 p( ?& d* G* M/ w. E8 ^6 `
    DoThingsB();
# |4 i9 O! g' o$ ?}% R! T7 F# z( k2 B7 O, [5 Y- ~
/// <summary>3 k  ?9 y& u% _7 c" e% e1 U
/// 另外一个含有部分重复代码的函数% V! c7 B' @6 e. X6 ~2 b* b) I
/// </summary>8 |- q3 z9 x) O3 U
void OriginalB()
: q* E3 K7 z$ Q: N' k. ~& I. `{
7 ?4 _2 Z0 o1 K5 f; s8 F, z    DoThingsA();
0 }  C/ W7 h5 @6 E& @    // 没有重复的代码1 u9 E9 l' g" ^/ f1 K* u
    DoThingsB();; Q6 K2 d- m2 c' V; }9 t
}
: v+ q9 [# k4 }$ e7 j! O, `  现在我们重构含有部分相同代码的函数,用 delegate 模式重写它们:3 t. m+ J& s2 l5 x6 M7 |
/// <summary>% Q/ X2 p, w0 S  e
/// Encapsulate shared functionality
* U1 {8 z" l& i- P$ g/// </summary>
' n; q2 r$ S0 W& i- A. k6 o/// <param name="action">User defined action</param>$ ]' Q$ }: N* q2 l
void UniqueWrapper(Action action)
) i. i- l2 ~9 z# c{: p, P5 G/ m: l4 F, N
    DoThingsA();# H3 G8 I+ c9 x0 \5 M% T
    action();
6 t- N& z& b; ]% A' H8 }    DoThingsB();+ K  i3 ^7 x4 z' B7 k  A' x
}$ f8 _2 E3 q7 \
/// <summary>) I" K1 K; d( h
/// New implmentation of A% P( u" Q) k6 t' L- C: a4 p2 }
/// </summary>+ w) G" s0 y4 T2 {6 R$ Z
void NewA(). l5 o. [. a0 W5 a
{' p: I# z. S, \/ _2 N* U, ?4 L
    UniqueWrapper(() =>8 e6 s  E# f; \8 S$ f
    {3 S1 l$ q5 j+ e2 A
        // unique code
8 G, c7 ?2 w2 K" \7 u! }6 f6 b    });
  R$ S1 t0 b* s3 j0 f}- F% q" o# a' U) L
/// <summary>2 s5 j+ j3 h; Y+ m+ W
/// New implementation of B$ h! u, ~6 [4 a7 S
/// </summary>
1 T, @1 |2 H3 \5 t( _void NewB()
4 E4 ]6 I; J1 b! O{! G5 R4 Y, ~- m5 }, F2 x
    UniqueWrapper(() =>/ G' C" d  W! h- y. z5 s
    {6 ]1 W5 g/ q; o7 U
        // unique code( ]7 K3 F1 {! z! f- F+ V/ B
    });* @: v+ _0 _; i. V5 S
}
, Z. A' L' T1 I+ ~  2. 留意你开始分心的时候" c1 _7 ^: e: i/ y" Z, K
  当你发现自己在浏览 facebook 或微博,而不是在解决问题,这通常是一种你需要短暂休息的信号。离开办公桌,去喝一杯咖啡,或去跟同事聊 5 分钟。尽管这样做看起来有点反直觉,但长久去看,它会提高你的工作效率。, \8 m/ l+ F* U$ |5 |0 h
  3. 不要匆忙赶任务而放弃原则) w4 _( v; N4 l9 |. T
  当带着压力去解决一个问题或修改一个 bug,你很容易失去自制,发现自己匆匆忙忙,甚至完全忘了一直坚持的重要的测试过程。这通常会导致更多的问题,会让你在老板或同事眼里显得很不专业。1 c' q8 @- h1 E6 A+ \( W5 j( s
  4. 测试你完成的代码
: X  S2 N- U8 F6 d1 @  你知道你的代码能做什么,而且试了一下,它确实好用,但你实际上需要充分的验证它。分析所有可能的边界情况,测试在所有可能的条件下它都能如期的工作。如果有参数,传递一些预期范围外的值。传递一个 null 值。如果可能,让同事看看你的代码,问他们能否弄坏它。单元测试是到达这种目的的常规方法。
) m( I, o+ j8 d" [+ t0 H4 Z  5. 代码审查) }# W# R& [/ g2 F; f
  提交你的代码之前,找个同事一起坐下来,向他解释你做了哪些修改。通常,这样做的过程中你就能发现代码中的错误,而不需要同事说一句话。这比自己审查自己的代码要有效的多得多。# s" m) c/ l0 R4 Q
  6. 让代码更少
* a- x$ F' C( Z- m7 M  如果你发现写了大量的代码来解决一个简单的问题,你很可能做错了。下面的 boolean 用法是一个很好的例子:
7 I/ a" a" e8 m4 F% Cif (numMines > 0)7 E% Y' ~6 w/ M
{$ Z& ^- Y4 h, B' X, j8 Y6 v
   enabled=true;
+ J0 K5 M+ i# D4 d6 u}1 a% ~3 D- n/ d' z
else
+ v4 d# Q- F. S6 G+ Y7 S# k{7 D9 V' s3 c, Y/ @
   enabled=false;
" w3 o4 w0 V5 q4 X5 l} 4 c: Q6 e2 s0 d5 H+ C/ t2 ^9 G
  这时你应该写成这样:
8 L- `6 C% d# M6 Kenabled = numMines > 0; ) j7 n, n- T' c% ^# \: `4 m
  代码越少越好。这会使 bug 更少,重构可能性更小,出错的几率更小。要适度。可读性同等重要,你可不能这样做而使代码丧失可读性。! [! x, K5 r* j) I
  7. 为优雅的代码而努力0 i$ H4 M6 |: z; J$ h
  优雅的代码非常的易读,只用手边很少的代码、让机器做很少的运算就能解决问题。在各种环境中都做到代码优雅是很难的,但经过一段时间的编程,你会对优雅的代码是个什么样子有个初步的感觉。优雅的代码不会通过重构来获得。当你看到优雅的代码是会很高兴。你会为它自豪。例如,下面就是一个我认为是优雅的方式来计算多边形面积的方法:4 A8 \  i) @! I6 z- @; N6 q. g
static public double GetConvexPolygonArea (Vector2[] vertices)
0 F' [% B: c! ~6 l{/ _, U9 w6 n; _8 R
    double area = 0;
: b0 Q/ L9 g2 X    for (int i = 0; i < vertices.Length; i++)+ T5 g2 k$ [5 E* D6 `5 q
    {6 g- g' _8 g# {. A/ _" ~
        Vector2 P0 = vertices[i];% x# b/ [+ k: d8 A
        Vector2 P1 = vertices[(i + 1) % vertices.Length];
0 E+ E8 @" |0 z' P8 ?+ H4 v        area += P0.Wedge (P1);, F0 @; q1 Y7 f9 y/ a
    }3 P7 C# i" y, h/ Q; V8 s1 T+ Y
    return area / 2;
2 }6 y2 D; z& z0 S. y5 x} 8 o! G  @0 ~. K7 b* l& d5 m, l
  8. 编写不言自明的代码
( m- q- B& r% b6 W$ s4 {! y8 c( J  勿庸置疑,注释是编程中很重要的一部分,但能够不言自明的代码更胜一筹,因为它能让你在看代码时就能理解它。函数名变量名要慎重选择,好的变量/方法名字放到语言语义环境中时,不懂编程的人都能看懂。例如:/ \0 I9 B& G# M# U3 z3 O
void DamagePlayer (Player player, int damageAmount)1 m9 S/ M$ l( x9 K: R
{
6 ~) \& X$ |3 X# m" H    if (!player.m_IsInvincible && !player.m_IsDead). P' d4 G" T2 T/ A8 ^8 l
    {
* r- {9 h7 w$ ]( P4 M, R) Q        player.InflictDamage ( damageAmount );
5 D6 L, m; V  W6 i8 d6 h& i    }0 l5 z7 }! ]% K4 S
}
2 }2 x0 h8 v; K5 n. ^  能自我说明的代码不能代替注释。注释是用来解释“为什么”的,而自我说明的代码是来描述“是什么”的。
) p. H& R. r: `0 d( [( K( e  9. 不要使用纯数字
9 C. a9 c' ~6 J  直接把数字嵌入代码中是一种恶习,因为无法说明它们是代表什么的。当有重复时更糟糕——相同的数字在代码的多个地方出现。如果只修改了一个,而忘记了其它的。这就导致 bug。一定要用一个命名常量来代表你要表达的数字,即使它在代码里只出现一次。* H; B6 f$ a4 J. q7 C
  10. 不要做手工劳动5 j6 D" n) h$ E, {* Z
  当做一系列动作时,人类总是喜欢犯错误。如果你在做部署工作,并且不是一步能完成的,那你就是在做错事。尽量的让工作能自动化的完成,减少人为错误。当做工作量很大的任务时,这尤其重要。; L* q+ {; L- {, }9 b* z" ^# f3 n
  11. 避免过早优化
& l) h7 h# Q6 k* M7 K* c( t! o% T  当你要去优化一个已经好用的功能代码时,你很有可能会改坏它。优化只能发生在有性能分析报告指示需要优化的时候,通常是在一个项目开发的最后阶段。性能分析之前的优化活动纯属浪费时间,并且会导致 bug 出现。
3 u/ d) s6 y) {# E, V* l  好吧,我说是 10 个,但你却得到了额外赠送的一个!8 O+ u' e* L9 c( Y% X$ ~
  这些就是我要说的,我希望它们能帮助你改进编程开发过程。
5 k$ v9 A" f3 _# C. \8 d/ W  下次再见!祝快乐!8 a, m" W5 Z0 [' l' m
  Cheers, Paul.
作者: shutup    时间: 2013-1-2 13:54
来顶个贴。。。




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5