PDF:

Năm thói quen lập trình tốt trong PHP
Các thói quen giúp cho mã PHP của bạn dễ đọc và bảo trì
Nathan A. Good
Kỹ sư trưởng, tư vấn
Freelance Developer
12 06 2009
Giống như bất kỳ ngôn ngữ nào, các nhà phát triển có thể viết mã PHP với chất lượng từ rất tồi
tệ đến rất tốt. Tìm hiểu các thói quen lập chương trình tốt có thể giúp bạn vượt qua khoảng cách
về năng suất.
Tùy thuộc vào người mà bạn hỏi, sự khác biệt giữa một nhà phát triển tốt và một nhà phát triển
xuất sắc, về mặt năng xuất, là một thừa số từ 10 đến 20 lần. Một nhà phát triển xuất sắc có năng
suất cao hơn do anh ta có kinh nghiệm và các thói quen tốt. Khi các thói quen lập chương trình
kém luồn lách vào trong mã của bạn, chúng sẽ bòn rút hết năng suất. Bài viết này chứng tỏ một số
thói quen lập chương trình tốt có thể giúp bạn trở thành một lập trình viên tốt hơn.
Ngoài việc cho phép bạn để xây dựng mã năng suất hơn, những thói quen này có thể giúp bạn xây
dựng mã bền vững cho suốt cuộc đời của ứng dụng. Bất cứ mã nào mà bạn viết ra nhiều khả năng là
hầu hết cuộc đời của nó sẽ trải qua khâu bảo trì; việc bảo trì ứng dụng có chi phí lớn. Việc tạo ra các
thói quen mã hóa tốt sẽ nâng cao các nhân tố thiết kế như khả năng lắp ghép mô đun và mã của
bạn sẽ dễ hiểu hơn và do đó bảo trì dễ dàng và có chi phí rẻ hơn.
Các thói quen mã hóa xấu dường như luôn đi kèm các nhược điểm trong mã và có thể làm cho mã
khó thay đổi mà không sinh thêm ra các khiếm khuyết mới. Dưới đây là năm thói quen tốt, khi áp
dụng vào mã PHP của bạn, sẽ giúp bạn tránh được các cạm bẫy này:
1. Chọn các tên thích hợp.
2. Làm từng mẩu nhỏ hơn.
3. Viết chú giải mã của bạn.
4. Xử lý các điều kiện lỗi.
5. Không bao giờ sao chép và dán liên tục.
Phần tiếp theo giải thích chi tiết về những thói quen này.
© Copyright IBM Corporation 2009
Năm thói quen lập trình tốt trong PHP
Nhẫn hiệu đăng ký
Trang 1 của 16
developerWorks®
ibm.com/developerWorks/vn/
Chọn các tên thích hợp
Chọn các tên thích hợp là thói quen quan trọng nhất vì các tên mô tả làm cho mã dễ đọc và dễ
hiểu hơn. Tính dễ hiểu của mã của bạn quyết định việc nó có thể bảo trì được trong tương lai hay
không. Ngay cả khi mã bạn viết không chứa bất kỳ chú giải nào, nếu nó dễ hiểu, sẽ dễ dàng hơn
cho bạn hay một người nào khác thay đổi khi cần thiết. Mục đích của bạn, khi tập thói quen này, sẽ
là chọn cách đặt tên tốt để làm cho việc đọc mã của bạn giống như đọc một quyển sách.
Thói quen xấu: Các tên không có nghĩa hay nhập nhằng
Liệt kê 1 hiển thị mã có các tên biến ngắn quá mức, các chữ viết tắt là rất khó hiểu và các tên
phương thức không mô tả rõ ràng những gì mà các phương thức làm. Các tên phương thức ngụ ý
các phương thức thực hiện một việc, trong khi thực sự chúng lại làm một cái gì đó khác, có thể đặc
biệt rắc rối do chúng gây nhầm lẫn.
Liệt kê 1. Thói quen xấu: Các tên không có nghĩa hay nhập nhằng
<?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");
?>
Thói quen tốt: Các tên phản ánh mà cô đọng
Liệt kê 2 biểu thị mã áp dụng thói quen đặt tên tốt. Các phương thức được đổi tên để phản ánh
đúng hơn về chúng sẽ làm gì và tại sao chúng làm như vậy. Các biến cũng được đổi tên để diễn tả
hơn. Một biến duy nhất rất ngắn là $i, trong liệt kê này là một biến vòng lặp. Mặc dù nhiều người có
thể không đồng ý, một tên ngắn cho biến vòng lặp là có thể chấp nhận được — thậm chí là tốt —
bởi vì nó là một chỉ báo rõ ràng về chức năng.
Liệt kê 2. Thói quen tốt: Các tên phản ánh mà cô đọng
<?php
define
define
define
define
define
define
define
('MONDAY', 1);
('TUESDAY', 2);
('WEDNESDAY', 3);
('THURSDAY', 4);
('FRIDAY', 5);
('SATURDAY', 6);
('SUNDAY', 7);
Năm thói quen lập trình tốt trong PHP
Trang 2 của 16
ibm.com/developerWorks/vn/
developerWorks®
/*
*
* @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");
?>
Bạn được khuyến khích phân nhỏ các điều kiện lớn thành một phương thức và đặt tên phương
thức sao cho nó mô tả một điều kiện. Kỹ thuật này làm cho mã dễ đọc hơn và biểu lộ ra ngoài
(externalize) một điều kiện sao cho nó có thể được trừu tượng hóa và thậm chí còn tái sử dụng
được. Nếu các khoản trong điều kiện thay đổi, thì cũng dễ dàng cập nhật phương thức hơn. Bởi vì
phương thức có một tên có ý nghĩa, nên mã không bị mất đi ý nghĩa của nó hoặc sẽ trở thành khó
đọc.
Làm từng mẩu nhỏ hơn
Rất dễ dàng tập trung ngay vào việc giải quyết một vấn đề và bắt đầu viết mã ngay. Trong khi bạn
đang giải quyết một vấn đề trước mắt, bạn liên tục gõ vào, làm cho các hàm của bạn càng ngày
càng dài ra. Về lâu dài đây không phải là một vấn đề, miễn là sau đó bạn quay lại và cấu trúc lại mã
thành các đoạn nhỏ hơn.
Cấu trúc lại mã là một ý tưởng tuyệt vời, nhưng bạn nên tập thói quen viết các phương thức ngắn
hơn, tập trung hơn ngay từ đầu. Các phương thức ngắn hơn có thể được xem trong một cửa sổ sẽ
dễ hiểu hơn. Khi một phương thức quá dài, không thể xem tất cả cùng một lúc trong một cửa sổ, nó
sẽ làm giảm tính dễ hiểu bởi vì bạn không thể nhanh chóng theo dõi toàn bộ dòng chảy của nó từ
đầu đến cuối.
Khi xây dựng các phương thức, bạn cũng nên tạo thói quen xây dựng chúng sao cho chúng làm
một việc và chỉ một việc mà thôi. Có một số lý do cho việc tập trung cao độ như vậy khi viết phương
thức của bạn. Trước tiên, các phương thức được tái sử dụng một cách dễ dàng hơn khi chúng chỉ
làm một việc và làm tốt việc đó. Thứ hai, các phương thức như vậy dễ dàng thử nghiệm hơn. Thứ
Năm thói quen lập trình tốt trong PHP
Trang 3 của 16
developerWorks®
ibm.com/developerWorks/vn/
ba, các phương thức như vậy càng dễ hiểu và dễ thay đổi hơn — nếu cần thiết — khi chúng càng
đơn giản hơn.
Thói quen xấu: Các hàm dài thực sự (làm nhiều việc)
Liệt kê 3 cho thấy một hàm dài. Nó rắc rối vì nhiều lẽ khác. Nó làm nhiều việc, do đó nó sẽ không
gắn kết chặt chẽ. Nó sẽ khó hiểu, khó gỡ rối và khó thử nghiệm hơn. Nó kéo dài suốt một tệp tin và
xây dựng một danh sách các mục, nó gán các giá trị cho các đối tượng, nó thực hiện một số phép
tính toán và nhiều hơn nữa.
Liệt kê 3. Thói quen xấu: Các hàm dài
<?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>[email protected]</managingEditor>" .
"<webMaster>[email protected]</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'];
Năm thói quen lập trình tốt trong PHP
Trang 4 của 16
ibm.com/developerWorks/vn/
$feed
$feed
$feed
$feed
$feed
$feed
$feed
.=
.=
.=
.=
.=
.=
.=
developerWorks®
"<item>";
"<title>" . $title . "</title>";
"<link>" . $link . "</link>";
"<description> " . $description . "</description>";
"<pubDate>" . $date . "</pubDate>";
"<guid>" . $guid . "</guid>";
"</item>";
}
$feed .= "</rss";
// write the feed out to the server...
echo($feed);
}
?>
Nếu bạn thêm nhiều hơn nữa vào phương thức này, nó sẽ sớm trở nên hầu như không thể bảo trì
được.
Thói quen tốt: Các hàm tập trung, quản lý được
Liệt kê 4 biểu thị một cách viết lại phương thức gốc để cho dễ đọc hơn và cô đọng hơn. Trong ví dụ
này, phương thức dài đã được phân thành các phương thức nhỏ hơn mà mỗi phương thức làm một
việc và làm tốt việc đó. Kết quả sẽ là khả năng sử dụng lại tốt hơn trong tương lai và sẽ dễ dàng thử
nghiệm hơn.
Liệt kê 4. Thói quen tốt: Các hàm tập trung, quản lý được
<?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>[email protected]</managingEditor>" .
"<webMaster>[email protected]</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>";
Năm thói quen lập trình tốt trong PHP
Trang 5 của 16
developerWorks®
ibm.com/developerWorks/vn/
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);
}
?>
Năm thói quen lập trình tốt trong PHP
Trang 6 của 16
ibm.com/developerWorks/vn/
developerWorks®
Việc phân nhỏ các phương thức dài cũng có thể dẫn đến sự suy giảm trở lại, vì vậy hãy cẩn thận, khi
tập thói quen tốt này, đừng lạm dụng làm quá lên. Rất có thể việc chia tách mã nhiều đến mức làm
nó cũng khó đọc như khi tất cả còn là một hàm nguyên khối.
Viết chú giải mã của bạn
Việc chú giải mã của bạn, thoạt đầu đôi khi có vẻ cũng khó khăn như việc viết mã. Biết phải chú giải
những gì đòi hỏi phải khéo léo vì rất dễ bị lôi kéo thành chú giải những gì mà mã đang làm. Một ý
tưởng tốt hơn là chú giải mục đích của mã là gì. Trong các khối đầu đề của hàm, khi mà mục đích
của hàm có thể còn chưa hiển nhiên, hãy nói cho người đọc biết các đầu vào và các đầu ra của các
phương thức là gì và mục đích nguyên thủy của nó.
Việc chú giải mã đang làm gì là rất phổ biến, nhưng không cần thiết. Nếu mã lộn xộn đến mức mà
bạn phải ghi chú nó đang làm gì, hãy coi đây như là một gợi ý rằng bạn nên viết lại mã để làm cho
nó dễ hiểu hơn. Hãy tập thói quen chọn đặt tên thích hợp, dùng các phương thức và các cấu trúc
nhỏ hơn để làm cho mã của bạn dễ đọc hơn mà không phải chú giải nó làm gì.
Thói quen xấu: Chú giải hàm thiếu và thừa
Các chú giải trong Liệt kê 5 chỉ nói cho người đọc mã đang làm gì — đó là việc lặp lại thông qua
một vòng lặp hay nó thêm một số. Nhưng cái đang thiếu là lý do tại sao nó đang làm những gì nó
làm. Sẽ khó khăn cho ai đó đang bảo trì mã này nếu muốn biết mã có thể được thay đổi an toàn
mà không đưa thêm vào các nhược điểm mới hay không.
Liệt kê 5. Thói quen xấu: Chú giải hàm thiếu và thừa
<?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)
{
Năm thói quen lập trình tốt trong PHP
Trang 7 của 16
developerWorks®
ibm.com/developerWorks/vn/
$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");
?>
Thói quen tốt: Các hàm và các lớp có chú giải
Các chú giải trong Liệt kê 6 thông báo cho người đọc mục đích của các lớp và các phương thức.
Các chú giải này cho biết lý do tại sao các hàm đang làm những gì mà chúng đang làm, sẽ có ích
nhiều hơn trong tương lai khi mã được bảo trì. Các điều kiện có thể thay đổi và đòi hỏi mã của bạn
phải được sửa đổi, và đó sẽ là một nhiệm vụ dễ dàng hơn nếu có thể nhanh chóng tìm ra mục đích
mã của bạn đã là gì khi bắt đầu.
Liệt kê 6. Thói quen tốt: Các hàm và các lớp có chú giải
<?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;
}
Năm thói quen lập trình tốt trong PHP
Trang 8 của 16
ibm.com/developerWorks/vn/
developerWorks®
/**
* 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");
?>
Xử lý các lỗi
Người ta đã nói rằng khi bạn viết các ứng dụng chắc chắn, mã xử lý lỗi dường như tuân theo quy
luật 80/20: 80 phần trăm mã dành cho xử lý các trường hợp ngoại lệ và kiểm tra hợp lệ, và 20 phần
trăm mã thực tế làm công việc. Viết mã để làm cho việc mã hóa đi theo tuyến đường may mắn
Năm thói quen lập trình tốt trong PHP
Trang 9 của 16
developerWorks®
ibm.com/developerWorks/vn/
(happy-path coding) là thói quen khá tự nhiên. Điều này có nghĩa là viết mã hoạt động tốt cho
các điều kiện cơ sở, khi tất cả các dữ liệu là hợp lệ và tất cả các điều kiện đúng như mong đợi. Tuy
nhiên, mã như vậy có thể dễ hỏng trong cuộc đời của ứng dụng. Ở cực khác, bạn có thể dành quá
nhiều thời gian viết mã cho các điều kiện mà có thể không bao giờ gặp phải.
Thói quen này là về việc tìm sự cân bằng giữa thực hiện xử lý lỗi đúng mức và không thực hiện mạ
vàng nhiều tới mức mà mã của bạn sẽ không bao giờ được hoàn tất.
Thói quen xấu: Hoàn toàn không xử lý lỗi
Các mã trong Liệt kê 7 biểu thị một số thói quen xấu. Thói quen xấu thứ nhất là không kiểm tra các
thông số đưa vào, mặc dù bạn biết vào thời điểm này một tham số trong một trạng thái nhất định sẽ
gây ra một ngoại lệ trong phương thức của bạn. Thói quen xấu thứ hai là các mã gọi ra một phương
thức có thể đưa ra một ngoại lệ mà không xử lý nó. Mã này sẽ để mặc tác giả hoặc người bảo trì
đoán mò về nguồn gốc của vấn đề — khi các vấn đề bắt đầu xảy ra.
Liệt kê 7. Thói quen xấu: Không xử lý các điều kiện lỗi
<?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");
?>
Thói quen tốt: Lập trình có tính phòng vệ tốt
Liệt kê 8 biểu thị việc xử lý và đưa ra các ngoại lệ một cách có ý nghĩa. Không chỉ thực hiện xử lý
lỗi bổ sung để làm cho mã vững chãi hơn, mà còn trợ giúp cho tính dễ đọc và dễ hiểu hơn. Cách
thức xử lý các ngoại lệ cung cấp một chỉ báo tốt về cái mà tác giả ban đầu tìm kiếm khi viết phương
thức này.
Liệt kê 8. Thói quen tốt: Lập trình có tính phòng vệ tốt
<?php
/**
* This is the exception thrown if the day of the week is invalid.
* @author nagood
*
*/
Năm thói quen lập trình tốt trong PHP
Trang 10 của 16
ibm.com/developerWorks/vn/
developerWorks®
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");
}
?>
Mặc dù việc kiểm tra các thông số là xác nhận hợp lệ — và sẽ có ích cho bất kỳ ai khi sử dụng các
hàm của bạn nếu bạn yêu cầu các tham số theo một cách nhất định — bạn nên kiểm tra chúng và
đưa ra các ngoại lệ có ý nghĩa:
• Xử lý các ngoại lệ càng gần nơi xảy ra vấn đề càng tốt.
• Xử lý cụ thể từng ngoại lệ.
Không bao giờ liên tục sao chép và dán
Khả năng sao chép mã từ một nơi và dán nó vào trong trình soạn thảo mã của bạn là một con dao
hai lưỡi. Một mặt, nó tránh được rất nhiều lỗi khi bạn đang gõ lại từ một ví dụ hoặc một bản mẫu.
Mặt khác, nó làm lây lan nhanh cách viết mã giống nhau quá dễ dàng.
Năm thói quen lập trình tốt trong PHP
Trang 11 của 16
developerWorks®
ibm.com/developerWorks/vn/
Hãy cảnh giác chống lại việc sao chép và dán mã giữa các phần của ứng dụng của bạn. Khi bạn thấy
mình đang làm điều đó, hãy dừng lại và tự hỏi, làm thế nào để có thể viết lại phần mã mà bạn đang
sao chép để thành một cái gì đó có thể tái sử dụng. Đặt mã vào chỉ một nơi cho phép bạn bảo trì
mã của mình một cách dễ dàng hơn, ở một mức độ lớn, bởi vì các thay đổi cần được thực hiện chỉ
ở một nơi thôi.
Thói quen xấu: Các phần mã giống nhau
Liệt kê 9 hiển thị một cặp phương thức gần giống hệt nhau, ngoại trừ một vài giá trị ở đâu đó. Có
sẵn các công cụ để giúp bạn tìm thấy các mã được sao chép và dán (xem Tài nguyên).
Liệt kê 9. Thói quen xấu: Các phần mã giống nhau
<?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") {
Năm thói quen lập trình tốt trong PHP
Trang 12 của 16
ibm.com/developerWorks/vn/
developerWorks®
$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");
?>
Thói quen tốt: Các hàm sử dụng lại được với các tham số
Liệt kê 10 hiển thị mã được sửa đổi để đặt phần mã được sao chép vào trong một phương thức.
Các phương thức khác đã được thay đổi để chuyển giao công việc cho phương thức mới này. Việc
xây dựng phương thức chung cần một số thời gian thiết kế và chắc chắn làm như vậy sẽ làm cho
bạn tạm dừng và suy nghĩ thay vì theo bản năng sử dụng các kết hợp phím tắt sao chép-và-dán.
Nhưng bạn sẽ được bù lại khoảng thời gian mà bạn đã đầu tư ngay khi phần mã chung cần phải
được thay đổi lần đầu tiên.
Liệt kê 10. Thói quen tốt: Các hàm sử dụng lại được với các tham số
<?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
Năm thói quen lập trình tốt trong PHP
Trang 13 của 16
developerWorks®
ibm.com/developerWorks/vn/
* @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");
?>
Kết luận
Nếu bạn tập các thói quen tốt đã thảo luận trong bài viết này trong khi đang phát triển mã PHP của
bạn, bạn sẽ xây dựng mã dễ đọc, hiểu và bảo trì. Việc xây dựng một mã bảo trì dễ dàng theo cách
này sẽ cho phép bạn gỡ lỗi, sửa chữa và mở rộng mã của bạn với mức rủi ro thấp hơn.
Việc chọn đặt tên thích hợp và tổ chức mã của bạn thành các đoạn nhỏ hơn làm cho mã của bạn dễ
đọc hơn. Việc chú giải mục đích của mã của bạn làm cho mục đích của nó dễ hiểu và mở rộng hơn.
Việc xử lý đúng đắn các lỗi làm mã của bạn vững chãi hơn. Cuối cùng, việc từ bỏ cái nạng sao chép
và dán cho phép bạn giữ sạch mã của mình.
Năm thói quen lập trình tốt trong PHP
Trang 14 của 16
ibm.com/developerWorks/vn/
developerWorks®
Tài nguyên
Học tập
• Đọc "Build seven good object-oriented habits in PHP" để bắt đầu chuyển tiếp từ lập trình theo
thủ tục sang lập trình hướng-đối tượng.
• Đọc Code Complete của Steven C. McConnell để tìm hiểu thêm về cách viết mã có chất lượng
cao.
• Tìm hiểu về "Advanced PHP V5 objects" để xây dựng mã PHP có thể sử dụng lại.
• Đọc về "Five common PHP design patterns" để tìm hiểu làm thế nào để áp dụng các mẫu
thiết kế hướng-đối tượng trong PHP.
• Đọc về "Five more PHP design patterns" để học cách làm thế nào để áp dụng nhiều mẫu thiết
kế hướng-đối tượng hơn trong PHP.
• Trong phần Architecture zone trên developerWorks, nhận các tài nguyên mà bạn cần để nâng
cao kỹ năng của bạn trong vũ đài kiến trúc.
• PHP.net là tài nguyên trung tâm cho các nhà phát triển PHP.
• Xem "Danh sách khuyến khích đọc PHP."
• Duyệt qua tất cả các nội dung PHP trên developerWorks.
• Mở rộng các kỹ năng của bạn bằng cách xem các tài nguyên dự án PHP của developerWorks
của IBM.
• Để nghe phỏng vấn và các cuộc thảo luận thú vị dành cho các nhà phát triển phần mềm, hãy
xem developerWorks podcasts.
• Bạn cần sử dụng một cơ sở dữ liệu với PHP? Xem Zend Core for IBM, một môi trường phát
triển và sản xuất PHP dễ cài đặt, trơn tru, có sẵn để dùng ngay, có hỗ trợ IBM DB2 V9.
• Theo dõi sát các sự kiện kỹ thuật và webcasts của developerWorks.
• Xem các hội nghị sắp tới, các cuộc triển lãm thương mại, webcasts và các sự kiện khác trên
khắp thế giới đang được các nhà phát triển mã nguồn mở của IBM quan tâm đến.
• Truy cập vào Vùng mã nguồn mở của developerWorks để cập nhật rất nhiều dự án, các công
cụ và các thông tin hướng dẫn để giúp bạn phát triển với các công nghệ mã nguồn mở và sử
dụng chúng với các sản phẩm của IBM.
• Theo dõi và tìm hiểu về các công nghệ mã nguồn mở và IBM và các chức năng sản phẩm với
các trình diễn mẫu theo yêu cầu miễn phí của developerWorks.
Lấy sản phẩm và công nghệ
• Đổi mới dự án phát triển mã nguồn mở tiếp theo của bạn với phần mềm dùng thử của IBM, có
sẵn để tải về hoặc trên đĩa DVD.
• Tải về các phiên bản đánh giá sản phẩm IBM và nhận các sản phẩm phần mềm trung gian
và các công cụ phát triển ứng dụng thực hành từ DB2®, Lotus®, Rational®, Tivoli® và
WebSphere®.
Thảo luận
• Tham gia vào developerWorks blogs và dành tâm trí cho cộng đồng developerWorks.
• Tham gia vào Diễn đàn PHP: Phát triển các ứng dụng PHP với sản phẩm quản lý thông tin
của IBM (DB2, ID) của developerWorks.
Năm thói quen lập trình tốt trong PHP
Trang 15 của 16
developerWorks®
ibm.com/developerWorks/vn/
Đôi nét về tác giả
Nathan A. Good
Nathan Good sống tại vùng Twin Cities của bang Minnesota. Về chuyên môn, ông làm
công việc phát triển phần mềm, kiến trúc phần mềm và quản trị các hệ thống. Khi ông
không viết phần mềm, ông rất thích xây dựng các máy chủ và máy tính cá nhân, đọc
và làm việc với các công nghệ mới và cố gắng khuyến khích bạn bè của mình chuyển
sang phần mềm mã nguồn mở
© Copyright IBM Corporation 2009
(www.ibm.com/legal/copytrade.shtml)
Nhẫn hiệu đăng ký
(www.ibm.com/developerworks/vn/ibm/trademarks/)
Năm thói quen lập trình tốt trong PHP
Trang 16 của 16