[译]Five good programming habits in PHP

Five good programming habits in PHP

5个PHP编程的好习惯

原文地址:http://www.ibm.com/developerworks/opensource/library/os-php-5goodhabits/index.html?ca=dgr-jw64os-php-5goodhabits&S_TACT=105AGY46&S_CMP=GRsitejw64

Depending on whom you ask, the difference between a good developer and an excellent developer, in terms of productivity, is a factor of 10 to 20. An excellent developer is more productive because of his experience and good habits. When poor programming habits sneak into your code, they're a drain on productivity. This article demonstrates some good programming habits that can make you a better programmer.

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

In addition to enabling you to build code more productively, these habits can help you build code sustainable for an application's lifetime. Any code you write is likely to spend most of its lifetime in maintenance; application maintenance is a large expense. Establishing good coding habits will enhance design factors like modularity, and your code will be easier to understand and, thus, easier and cheaper to maintain.

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

Bad coding habits seem to accompany defects in code and can cause code to be difficult to change without introducing new defects. The following five good habits, when applied to your PHP code, will help you avoid these pitfalls:

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

  1. Use good naming.
  2. Take smaller bites.
  3. Document your code.
  4. Handle error conditions.
  5. Never, ever, copy and paste.
  1. 使用友好的命名方式。
  2. 使用更精悍短小的代码。
  3. 注释你的代码。
  4. 编写异常处理。
  5. 永远,永远不要复制粘贴.(玉米:我深深的同意这一点)

 

The next sections explain these habits in detail.

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

 

Use good naming

良好的命名方式


Using good naming is the most important habit because descriptive names make code easier to read and understand. The understandability of your code ultimately determines whether it can be maintained in the future. Even if the code you write contains no comments, if it's easy to understand, it will be much easier for you or someone else to change, if necessary. Your aim, when developing this practice, should be to use good naming to make your code read much like a book.

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

 

Bad habit: Ambiguous or meaningless names

坏习惯:无意义的难懂的命名

Listing 1 shows code that includes overly short variable names, abbreviations that are difficult to understand, and method names that don't clearly describe what the methods do. Method names that imply the methods do one thing when they really do something else can be particularly problematic because they're misleading.

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


Listing 1. Bad: Ambiguous or meaningless names

 

<?php

function getNBDay($d)
{
switch($d) {
case 5:
case 6:
case 7:
return 1;
default:
return ($d + 1);
}
}

$day = 5;

$nextDay = getNBDay($day);

echo ("Next day is: " . $nextDay . "\n");

?>

 

Good habit: Reflective yet concise names

好习惯:简单明了的命名

Listing 2 demonstrates code that uses good naming habits. Methods are renamed to be more reflective of what they do and why. Variables are renamed to be more descriptive, as well. The only variable that's left short is $i, which in this listing is a looping variable. Although many people may disagree, a short name for the looping variable is acceptable — even good — because it's a clear indicator of functionality.

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


Listing 2. Good: Reflective yet concise names

<?php

define ('MONDAY', 1);
define ('TUESDAY', 2);
define ('WEDNESDAY', 3);
define ('THURSDAY', 4);
define ('FRIDAY', 5);
define ('SATURDAY', 6);
define ('SUNDAY', 7);

/*
*
* @param $dayOfWeek
* @return int Day of week, with 1 being Monday and so on.
*/
function findNextBusinessDay($dayOfWeek)
{
$nextBusinessDay = $dayOfWeek;

switch($dayOfWeek) {
case FRIDAY:
case SATURDAY:
case SUNDAY:
$nextBusinessDay = MONDAY;
break;
default:
$nextBusinessDay += 1;
break;
}

return $nextBusinessDay;
}

$day = FRIDAY;

$nextBusDay = findNextBusinessDay($day);

echo ("Next day is:" . $nextBusDay . "\n");

?>

 

You are encouraged to break up large conditions into a method and name the method so it describes the condition. This technique makes the code easier to read and externalizes the condition so it can be abstracted and perhaps even reused. If the terms of the condition change, it's easier to update the method. Because the method has a meaningful name, the code doesn't lose its meaning or become difficult to read.

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


Take smaller bites

使用更少的代码


It's easy to get focused on solving a problem and start coding away. While you're solving an immediate problem, you keep typing, letting your functions get longer and longer. That's not a problem over the long term, as long as you go back later and refactor the code into smaller bites.

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

 

Refactoring is a great idea, but you should develop the habit of writing shorter, more focused methods the first time. Shorter methods that can be viewed in one window are easier to understand. When a method is too long to be viewed all at once in a window, it decreases in understandability because you can't quickly follow its entire flow from beginning to end.

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

 

When building methods, you should also form the habit of constructing them so they do one thing and one thing only. There are several reasons for such diligent focus in your method writing. First, methods are more easily reused when they do one thing and do it well. Second, such methods are easier to test. Third, such methods are easier to understand and change — if necessary — the simpler they are.

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

 

Bad habit: Really long functions (that do a lot)

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


Listing 3 shows a long function. It's problematic for a couple of other reasons. It does many things, so it isn't cohesive. It will be harder to understand, debug, and test. It iterates through a file and builds a list of entries, it assigns the values to objects, it does some calculations, and more.

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


Listing 3. Bad: Long functions  坏习惯:过长函数

<?php

function writeRssFeed($user)
{
// Get the DB connection information


// look up the user's preferences...
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());

// Query
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
mysql_real_escape_string($user));

$result = mysql_query($query, $link);

$max_stories = 25; // default it to 25;

if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row['max_stories'];
}

// go get my data
$perfsQuery = sprintf("SELECT * FROM stories WHERE post_date = '%s'",
mysql_real_escape_string());

$result = mysql_query($query, $link);


$feed = "<rss version=\"2.0\">" .
"<channel>" .
"<title>My Great Feed</title>" .
"<link>http://www.example.com/feed.xml</link>" .
"<description>The best feed in the world</description>" .
"<language>en-us</language>" .
"<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
"<docs>http://www.example.com/rss</docs>" .
"<generator>MyFeed Generator</generator>" .
"<managingEditor>editor@example.com</managingEditor>" .
"<webMaster>webmaster@example.com</webMaster>" .
"<ttl>5</ttl>";

// 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 .= "<item>";
$feed .= "<title>" . $title . "</title>";
$feed .= "<link>" . $link . "</link>";
$feed .= "<description> " . $description . "</description>";
$feed .= "<pubDate>" . $date . "</pubDate>";
$feed .= "<guid>" . $guid . "</guid>";
$feed .= "</item>";
}

$feed .= "</rss";

// write the feed out to the server...
echo($feed);

}

?>

 

If you add more to this method, it will soon become virtually unmaintainable.

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

 

Good habit: Manageable, focused functions

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



Listing 4. Good: Manageable, focused functions

<?php

function createRssHeader()
{
return "<rss version=\"2.0\">" .
"<channel>" .
"<title>My Great Feed</title>" .
"<link>http://www.example.com/feed.xml</link>" .
"<description>The best feed in the world</description>" .
"<language>en-us</language>" .
"<pubDate>Tue, 20 Oct 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>Tue, 20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
"<docs>http://www.example.com/rss</docs>" .
"<generator>MyFeed Generator</generator>" .
"<managingEditor>editor@example.com</managingEditor>" .
"<webMaster>webmaster@example.com</webMaster>" .
"<ttl>5</ttl>";
}

function createRssFooter()
{
return "</channel></rss>";
}

function createRssItem($title, $link, $desc, $date, $guid)
{
$item .= "<item>";
$item .= "<title>" . $title . "</title>";
$item .= "<link>" . $link . "</link>";
$item .= "<description> " . $description . "</description>";
$item .= "<pubDate>" . $date . "</pubDate>";
$item .= "<guid>" . $guid . "</guid>";
$item .= "</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);
}
?>

 

Breaking down longer methods can offer diminishing returns, so be careful that when introducing this good habit you don't overdo it. It's possible to break up code so much that it's as difficult to read as it was when it was all one monolithic function.

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

 

 


Document your code

注释代码


Documenting your code well sometimes seems as difficult as writing it in the first place. Knowing what to document is tricky because it's tempting to document what the code is doing. Documenting the code's intention is a better idea. In the header blocks of functions that may not be obvious, tell the reader the expected inputs and outputs of the methods and the original intent.

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

 

Documenting what the code is doing is common, but unnecessary. If the code is so confusing that you have to document what it's doing, take that as a hint that you should rewrite the code to make it easier to understand. Develop the habit of using good naming and smaller methods and structures to make your code more readable without having to comment what it does.

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

 

Bad habit: Missing and redundant function documentation

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


The comments in Listing 5 merely tell the reader what the code is doing — that it's iterating through a loop or that it's adding a number. But what is missing is why it's doing what it's doing. It would be difficult for someone maintaining this code to know whether the code can be safely changed without introducing new defects.

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


Listing 5. Bad: Missing and redundant function documentation压根没胡或者叽叽歪歪的函数注释

<?php

class ResultMessage
{
private $severity;
private $message;

public function __construct($sev, $msg)
{
$this->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");

?>

 

Good habit: Documented functions and classes

好习惯: 注释函数和类


The comments in Listing 6 tell the reader the intentions of the classes and methods. The comments tell why the functions are doing what they're doing, which will be much more helpful in the future when the code is being maintained. Conditions may change that require your code to be modified, and that's an easier task if it's simple to find out what your code's purpose was in the first place.

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


Listing 6. Good: Documented functions and classes  好习惯:注释函数和类

<?php
/**
* The ResultMessage class holds a message that can be returned
* as a result of a process. The message has a severity and
* message.
*
* @author nagood
*
*/
class ResultMessage
{
private $severity;
private $message;

/**
* Constructor for the ResultMessage that allows you to assign
* severity and message.
* @param $sev See {@link getSeverity()}
* @param $msg
* @return unknown_type
*/
public function __construct($sev, $msg)
{
$this->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");

?>

 


Handle errors

异常处理


It's been said that when you're writing robust applications, error-handling code seems to follow the 80/20 rule: 80 percent of the code is dedicated to handling exceptions and validations, and 20 percent of the code does the actual work. It's natural when writing code to do happy-path coding. This means writing code that works well for the basic conditions, when all the data is valid and all the conditions are as expected. But such code can be fragile over the application's lifetime. At the other extreme, you may spend too much time writing code for conditions that may never be encountered.

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

 

This habit is about finding the balance between doing enough error handling and not doing so much gold plating that your code is never finished.

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

 

Bad habit: Not handling errors at all

坏习惯:不处理任何异常


The code in Listing 7 demonstrates a couple of bad habits. One is not checking the parameters coming in, even though you know at this point that a parameter in a certain state will cause an exception in your method. The second is that the code calls a method that can throw an exception without handling it. This code will leave the author or maintainer to make guesses about the source of the problem — when problems start occurring.


Listing 7. Bad: Not handling error conditions

<?php

// Get the actual name of the
function convertDayOfWeekToName($day)
{
$dayNames = array(
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday");
return $dayNames[$day];
}

echo("The name of the 0 day is: " . convertDayOfWeekToName(0) . "\n");
echo("The name of the 10 day is: " . convertDayOfWeekToName(10) . "\n");
echo("The name of the 'orange' day is: " . convertDayOfWeekToName('orange') . "\n");

?>

 

Good habit: Programming defensively

好习惯: 防守型编程

Listing 8 demonstrates handling and throwing exceptions in a meaningful way. Not only does the additional error handling make the code more robust, but it also helps with readability and understandability. The way the exceptions are handled provides a good indication of what the original author was looking for when the method was written.

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

 


Listing 8. Good: Programming defensively  好习惯:防守型编程

<?php

/**
* This is the exception thrown if the day of the week is invalid.
* @author nagood
*
*/
class InvalidDayOfWeekException extends Exception { }

class InvalidDayFormatException extends Exception { }

/**
* Gets the name of the day given the day in the week. Will
* return an error if the value supplied is out of range.
*
* @param $day
* @return unknown_type
*/
function convertDayOfWeekToName($day)
{
if (! is_numeric($day)) {
throw new InvalidDayFormatException('The value \'' . $day . '\' is an ' .
'invalid format for a day of week.');
}

if (($day > 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");
}

?>

 

Although checking parameters is validation — and it's helpful to anyone using your functions if you require parameters to be a certain way — you should check them and throw meaningful exceptions:

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

  • Handle exceptions as near to the problem as possible.
  • Handle each exception specifically.
  • 尽量抛出接近错误的异常.
  • 处理每个特殊的异常.

Never, ever copy and paste

永远,永远不要复制粘贴

The ability to copy code from one place and paste it into your code editor is a double-edged sword. On one hand, it saves a lot of errors when you're retyping from an example or a template. On the other hand, it makes proliferation of similar code way too easy.

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

 

Be on your guard against copying and pasting code between parts of your application. When you find yourself doing it, stop and ask yourself how you could rewrite the section of code you're copying to be something that you can reuse. Putting code in one place allows you to more easily maintain your code, to a large degree, because changes need to be made in only one place.

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

 

Bad habit: Similar sections of code

坏习惯:相似的代码块


Listing 9 shows a couple of methods that are nearly identical, except for a couple of values here and there. Tools are available to help you find copied and pasted code (see Resources).

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


Listing 9. Bad: Similar sections of code  相似的代码块

<?php
/**
* 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)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->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");
?>

 

Good habit: Reusable functions with parameters

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


Listing 10 shows the code modified to put the copied code into one method. The other methods have been changed to delegate the work to the new method. Building the common method takes some design time, and certainly doing so makes you pause and think instead of instinctively using the copy-and-paste shortcut key combinations. But you'll get back the time you invested the first time the common code needs to be changed.

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


Listing 10. Good: Reusable functions with parameters 好习惯 :可利用的带参函数

<?php
/*
* Counts the messages with the given severity in the array
* of messages.
*
* @param $messages An array of ResultMessage
* @return int Count of messages matching $withSeverity
*/
function countMessages($messages, $withSeverity)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->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");

?>

 


Conclusion

If you develop the good habits discussed in this article while developing your PHP code, you'll build code that is easy to read, understand, and maintain. Building easily maintainable code in this manner will enable you to debug, fix, and extend your code with lower risk.

Using good naming and organizing your code into smaller prices makes your code easier to read. Documenting the purpose of your code makes its intent easier to understand and extend. Handling errors properly makes your code more robust. Finally, breaking the crutch of copying and pasting lets you keep your code clean.

结论

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

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

-----------------------------------------------------

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

 

posted @ 2009-08-08 15:05  玉米疯收  阅读(622)  评论(3编辑  收藏  举报