热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

5个PHP编程的好习惯这些习惯能让你的代码在高效运行的同时提高可维护性

这些习惯能让你的代码在高效运行的同时提高可维护性。你写代码的时候,可能大部分时间都浪费在维护上了,程序的维护代价很高。培养良好的编程习惯,如模块化设计,可以让你的代码可读性更好,从而容易维护

有些人问,优秀程序员和大牛有什么区别,大概有10到20种吧。因为大牛有很好的编程习惯和丰富的经验,所以他们非常的高效。如果不好的编程习惯出现在你的代码里,你的代码效率就会降低。本文阐述一些好的编程习惯,他们可以让你成为更好的程序员。

这些习惯能让你的代码在高效运行的同时提高可维护性。你写代码的时候,可能大部分时间都浪费在维护上了,程序的维护代价很高。培养良好的编程习惯,如模块化设计,可以让你的代码可读性更好,从而容易维护。

代码中的问题往往伴随着不良的编程习惯,而且后者会导致代码不好修改并可能出现新的缺陷。下面有五个好的编程习惯,将帮你避免这些陷阱:

  1. 使用友好的命名方式。
  2. 使用更精悍短小的代码。
  3. 注释你的代码。
  4. 编写异常处理。
  5. 永远,永远不要复制粘贴.(玉米:我深深的同意这一点)

下面的章节将解释这些习惯。

使用友好的命名方式

良好的命名方式是最重要的编程习惯,因为好的命名会让代码易懂,好懂。代码的可读性决定它的可维护性。即使你在代码没有写注释,如果它可读性好的话,它也修改起来也会简单。你应该在练习开时就使用良好的命名方式,让你的代码像一本书一样。

例1 包含一个过短的变量名,写出这样的代码非常不好弄懂,而且函数名也没有清晰的描述出这个方法是做什么的。函数名表示了函数的功能,如果它却是做别的用途的,那就会误导别人。

Listing 1. Bad: Ambiguous or meaningless names

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

例2 则给出了使用良好命名方式的代码。重新命名函数是为了更好的反映它们的功能。变量也重新命名为描述性的。只有一个在循环中的$i还使用短的变量名。尽管有些人不同意,短变量名在循环中是请允许的——甚至更好些,因为它们清晰的起到了指针的功能。

Listing 2. Good: Reflective yet concise names

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

我鼓励你在函数中分隔长的条件给函数命名,以便于描述这个条件。(玉米:这句话啥意思?5555)这个技巧会让你的代码容易阅读和扩展,因此它可以被抽象复用。如果条件发生了改变,这样也会很容易更新函数 .由于方法有一个见名知义的名字,化码就不会失去它本来的意思或者变得难以理解。

使用更少的代码

编写代码、解决问题是一种容易的事情。当你解决一个正在发生的问题,编呀编,写呀写,你的方法越来越长。只要你回头使用更少的代码来重构,就是过了很久也没什么问题。

重构是个好主意,但你应该养成第一次就写出更短小精悍代码的习惯。在一个窗口上(玉米:不用翻页)就能看全的短小函数更容易理解。 要是一个函数长出了窗口,就很难理解了,因为你不能快速的从头到脚的浏览整个代码。

当构思一个方法的时候,你还应该养成一个让它们只做一件事情的习惯。以下因素写代码时应常注意。第一,只做一件事情的函数更易于复用。第二,这样的函数测试更方便。第三,这样的函数好读易懂方便改——如果必要的话——让它们尽可能的简单吧。

坏习惯:过长的函数(很多时候)

例三是过长函数的表现。它不知道自己要做什么。它做太多的事情,所以没有集成化。它更难以理解,不好Debug和测试。它遍历文件建立列表,它给对象赋值,它做一些计算,……它耕田,它浇水,甚至做更多事情。(^_^)

例三. 坏习惯:过长函数

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
" . "" . "" . "http://www.example.com/feed.xml" . "The best feed in the world" . "en-us" . "Tue, 20 Oct 2008 10:00:00 GMT" . "Tue, 20 Oct 2008 10:00:00 GMT" . "http://www.example.com/rss" . "MyFeed Generator" . "editor@example.com" . "webmaster@example.com" . "5";   // build the feed... while ($row = mysql_fetch_assoc($result)) { $title = $row['title']; $link = $row['link']; $description = $row['description']; $date = $row['date']; $guid = $row['guid'];   $feed .= ""; $feed .= ""; $feed .= "" . $link . ""; $feed .= " " . $description . ""; $feed .= "" . $date . ""; $feed .= "" . $guid . ""; $feed .= ""; }   $feed .= "

要是你再加更多东西到这个函数里,它会很快变得难以维护。

好习惯:可管理,集成化的函数

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
" . "" . "" . "http://www.example.com/feed.xml" . "The best feed in the world" . "en-us" . "Tue, 20 Oct 2008 10:00:00 GMT" . "Tue, 20 Oct 2008 10:00:00 GMT" . "http://www.example.com/rss" . "MyFeed Generator" . "editor@example.com" . "webmaster@example.com" . "5"; }   function createRssFooter() { return ""; }   function createRssItem($title, $link, $desc, $date, $guid) { $item .= ""; $item .= ""; $item .= "" . $link . ""; $item .= " " . $description . ""; $item .= "" . $date . ""; $item .= "" . $guid . ""; $item .= ""; return $item; }   function getUserMaxStories($db_link, $default) { $perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'", mysql_real_escape_string($user));   $result = mysql_query($perfsQuery, $db_link);   $max_stories = $default;   if ($row = mysql_fetch_assoc($result)) { $max_stories = $row['max_stories']; }   return $max_stories; }   function writeRssFeed($user) { // Get the DB connection information $settings = parse_ini_file("rss_server.ini");   // look up the user's preferences... $link = mysql_connect($settings['db_host'], $settings['user'], $settings['password']) OR die(mysql_error());   $max_stories = getUserMaxStories($link, 25);   // go get my data $newsQuery = sprintf("SELECT * FROM stories WHERE post_date = '%s'", mysql_real_escape_string(time()));   $result = mysql_query($newsQuery, $link);   $feed = createRssHeader();   $i = 0; // build the feed... while ($row = mysql_fetch_assoc($result)) { if ($i <$max_stories) { $title = $row['title']; $link = $row['link']; $description = $row['description']; $date = $row['date']; $guid = $row['guid'];   $feed .= createRssItem($title, $link, $description, $date, $guid);   $i++; } else { break; } }   mysql_close($link);   $feed .= createRssFooter();   // write the feed out to the server... echo($feed); } ?>

把长函数分割会导致效率降低,所以要注意,这个好习惯不要使用过度。这样做可能也会引起阅读性差,跟原来人家是一个整体时没什么区别。

注释代码

注释你的代码有时就像你刚着手写代码一样困难。明确注释内容很棘手,因为他要写出代码要做什么。注释变量是一个好主意。在函数头部注释可能不太明显时,就可以告诉阅读者函数要什么参数,有什么返回以及主要的意图。

通常大家会注释代码是做什么的,但这并不必要。如果代码让人困惑以至于你不得不写注释说它是做什么的,这就提示你应该重写它,使它更好懂。命名良好、更加短小、组织合理的代码习惯会让你的代码用不着注释就拥有很高的可读性。

坏习惯:压根没有或者叽叽歪歪的函数注释 (^_^)

例5 的注释只给出了代码在做什么——它的通过循环的遍历、加了个数。但是丢了为什么这么做和要做什么。 这会让别人难以不影响原代码的情形下安全修改的做出修改。

例5 :压根没胡或者叽叽歪歪的函数注释

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
severity = $sev; $this->message = $msg; }   public function getSeverity() { return $this->severity; }   public function setSeverity($severity) { $this->severity = $severity; }   public function getMessage() { return $this->message; }   public function setMessage($msg) { $this->message = $msg; } }   function cntMsgs($messages) { $n = 0; /* iterate through the messages... */ foreach($messages as $m) { if ($m->getSeverity() == 'Error') { $n++; // add one to the result; } } return $n; }   $messages = array(new ResultMessage("Error", "This is an error!"), new ResultMessage("Warning", "This is a warning!"), new ResultMessage("Error", "This is another error!"));   $errs = cntMsgs($messages);   echo("There are " . $errs . " errors in the result.n");   ?>

好习惯: 注释函数和类

例6 里的注释标明了类和函数的意图。注释表明方法做了什么和为什么做,这会对将来了解代码的意图很有帮助。环境的变化会需要你进行代码修改,这就会让很容易的知道开始时你代码是做什么的。

例6.好习惯:注释函数和类

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
82
83
84
85
severity = $sev; $this->message = $msg; }   /**
     * Returns the severity of the message. Should be one
     * "Information", "Warning", or "Error".
     * @return string Message severity
     */ public function getSeverity() { return $this->severity; }   /**
     * Sets the severity of the message
     * @param $severity
     * @return void
     */ public function setSeverity($severity) { $this->severity = $severity; }   public function getMessage() { return $this->message; }   public function setMessage($msg) { $this->message = $msg; } }   /*
 * Counts the messages with the given severity in the array
 * of messages.
 * 
 * @param $messages An array of ResultMessage
 * @return int Count of messages with a severity of "Error"
 */ function countErrors($messages) { $matchingCount = 0; foreach($messages as $m) { if ($m->getSeverity() == "Error") { $matchingCount++; } } return $matchingCount; }   $messages = array(new ResultMessage("Error", "This is an error!"), new ResultMessage("Warning", "This is a warning!"), new ResultMessage("Error", "This is another error!"));   $errs = countErrors($messages);   echo("There are " . $errs . " errors in the result.n");   ?>

异常处理

写健壮应用时经常会提到的异常处理,一般遵循着80/20原则: 80%的代码用于处理异常或者验证,20%的代码没什么实际的用途。原始的代码通常都是在乐观的环境下编写的。这意味着代码可以在数据正常、一切理解的基础环境中工作的很好。但是这种代码在其生命周期内是脆弱的。在极端的情形中,你得花更多的时间来未很可能永远不会发生的状况编写相应代码。

这个习惯就是要你处理全部的出错情况,而且如果要是不这么做,你的代码永远也完不成。

坏习惯:不处理任何异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

好习惯: 防守型编程

例8 表明处理并抛出异常是一件很有意义的事情。不只是额外的异常处理可以让代码健壮,但是这有助于提高代码的可读性。这种异常处理为原作者查看何时编写提供了一个很好的说明。

例8.好习惯:防守型编程

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
 6) || ($day <0)) { throw new InvalidDayOfWeekException('The day number '' . $day . '' is an ' . 'invalid day of the week. Expecting 0-6.'); }   $dayNames = array( "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"); return $dayNames[$day]; }   echo("The name of the 0 day is:  " . convertDayOfWeekToName(0) . "n");  
try { echo("The name of the 10 day is:  " . convertDayOfWeekToName(10) . "n"); } catch (InvalidDayOfWeekException $e) { echo ("Encountered error while trying to convert value:  " . $e->getMessage() . "n"); }  
try { echo("The name of the 'orange' day is:  " . convertDayOfWeekToName('orange') . "n"); } catch (InvalidDayFormatException $e) { echo ("Encountered error while trying to convert value:  " . $e->getMessage() . "n"); }   ?>

通过检验参数的全法性——这有助于他人使用你需要正确参数的函数——你应该检验它们并抛出异常的大意:

  • 尽量抛出接近错误的异常.
  • 处理每个特殊的异常.

永远,永远不要复制粘贴

把代码复制到你的编辑里的能力是一把双刃剑。一方面,它避免了你参照一些示例后重新再打一遍时出现的错误;另一方面,它让书写相似代码太简单了。

你要避免在你的程序应用中复制粘贴代码。当你发现自己在这样做时,停下来并问自己可不可以把复制的部分重复使用。把相同的代码放在同一个地方可以让你以后修改时更加的轻松,因为要改变都在一起。

坏习惯:相似的代码块

例9 表现了除了一些值所在位置之外很相近的几个方法。有些工具可以检验你的代码中复制粘贴的部分(去看看Resources)。

例9.相似的代码块

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
getSeverity() == "Error") { $matchingCount++; } } return $matchingCount; }   /**
 * Counts the number of messages found in the array of 
 * ResultMessage with the getSeverity() value of "Warning"
 * 
 * @param $messages An array of ResultMessage
 * @return unknown_type
 */ function countWarnings($messages) { $matchingCount = 0; foreach($messages as $m) { if ($m->getSeverity() == "Warning") { $matchingCount++; } } return $matchingCount; }   /**
 * Counts the number of messages found in the array of 
 * ResultMessage with the getSeverity() value of "Information"
 * 
 * @param $messages An array of ResultMessage
 * @return unknown_type
 */ function countInformation($messages) { $matchingCount = 0; foreach($messages as $m) { if ($m->getSeverity() == "Information") { $matchingCount++; } } return $matchingCount; }   $messages = array(new ResultMessage("Error", "This is an error!"), new ResultMessage("Warning", "This is a warning!"), new ResultMessage("Error", "This is another error!"));   $errs = countErrors($messages);   echo("There are " . $errs . " errors in the result.n"); ?>

好习惯:可复用的带参函数

例10 展示了把要复制的代码入到一个方法中的代码修改。另一个修改的方法则把工作代理给了一个新的方法 。编写一个通用的方法要花一些时间来设计,当然这会让你停下来思考,而不是用复制粘贴的组合快捷键。但是这样做会在以后修改时省回第一次多花的时间。

例10.好习惯 :可利用的带参函数

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
getSeverity() == $withSeverity) { $matchingCount++; } } return $matchingCount; }   /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Error"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */ function countErrors($messages) { return countMessages($messages, "Errors"); }   /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Warning"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */ function countWarnings($messages) { return countMessages($messages, "Warning"); }   /**
     * Counts the number of messages found in the array of 
     * ResultMessage with the getSeverity() value of "Warning"
     * 
     * @param $messages An array of ResultMessage
     * @return unknown_type
     */ function countInformation($messages) { return countMessages($messages, "Information"); }   $messages = array(new ResultMessage("Error", "This is an error!"), new ResultMessage("Warning", "This is a warning!"), new ResultMessage("Error", "This is another error!"));   $errs = countErrors($messages);   echo("There are " . $errs . " errors in the result.n");   ?>

结论

如果当你开发 PHP 的时候养成了本文中提到的好习惯,你写的代码将会好读、好懂、好维护。编写可维护代码的方式将让你的代码可以高度排错,并告别低级错误。

使用良好命名并用短代码块来组强你的代码会让你的代码简单明了。注明你代码的目的会让它的主旨明确易于理解。异常处理让你的代码健壮。最后,摒弃复制粘贴的恶习让你的代码整洁。

—————————————————–

玉米寄语:最后的这个复制粘贴的建议让我一身冷汗,想想其实有很多代码都是重复的工作,有时只是为了“快”,而把相似的代码又“复制”了一遍,虽然我没有使用ctrl+cv 但是也是写了很多类似的代码,看来,review的事儿可以在世界和平的事儿之前考虑了。


推荐阅读
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Python版Protobuf的安装和使用方法,包括版本选择、编译配置、示例代码等内容。通过学习本教程,您将了解如何在Python中使用Protobuf进行数据序列化和反序列化操作,以及相关的注意事项和技巧。 ... [详细]
  • MACElasticsearch安装步骤及验证方法
    本文介绍了MACElasticsearch的安装步骤,包括下载ZIP文件、解压到安装目录、启动服务,并提供了验证启动是否成功的方法。同时,还介绍了安装elasticsearch-head插件的方法,以便于进行查询操作。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 夏侯惇在曹魏集团的地位及其重要性
    本文介绍了夏侯惇在曹魏集团中的地位及其重要性。夏侯惇虽然没有特别显赫的战绩,但是他是曹操最信任的军事将领。通过对夏侯惇生平经历的回顾,可以看出他在曹魏集团的重要地位。从曹魏集团的二号人物到裨将、司马等职位的担任,夏侯惇一直是曹操最亲信的人之一。夏侯惇的历史地位在曹魏集团中不可忽视。 ... [详细]
author-avatar
oFoUro_877
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有