特定の状況にもよりますが、平均的な開発者は優秀な開発者よりも効率が 10% ~ 20% 低いことがよくあります。優れた開発者は、豊富な経験と優れたプログラミング習慣を備えているため、より効率的です。プログラミングの悪い習慣は効率に影響を与えます。この記事は、プログラミングの良い習慣を実践することで、より優れたプログラマーになるのに役立ちます。
これらの良いプログラミング習慣により、効率が向上するだけでなく、アプリケーションのライフサイクル全体にわたって保守が容易なコードを作成することもできます。作成したコードには多大なメンテナンスが必要になる場合があります。アプリケーションのメンテナンスには多大な費用がかかります。適切なプログラミング習慣を身につけると、設計品質 (モジュール性など) が向上し、コードが理解しやすくなり、保守が容易になると同時に、保守コストも削減できます。
プログラミングの悪い習慣はコードの欠陥を引き起こし、保守や変更を困難にし、変更時に他の欠陥を引き起こす可能性があります。以下に、PHP コードでこれらの落とし穴を回避するのに役立つ 5 つの良いプログラミング習慣を示します。
◆ 適切な名前を付けます。
◆小分けにします。
◆コードにコメントを追加します。
◆エラー状態を処理します。
◆コピー&ペーストは使用しないでください。
これらの習慣については、以下で詳しく説明します。
適切な名前を使用する
わかりやすい名前を付けるとコードが読みやすく理解しやすくなるため、適切な名前を使用することは最も重要なプログラミング習慣です。コードが理解しやすいかどうかは、将来メンテナンスできるかどうかによって決まります。コードのコメントが外されている場合でも、コードが理解しやすければ、将来の変更が非常に容易になります。この習慣の目標は、作成したコードを本と同じくらい読みやすく、理解しやすくすることです。
悪い習慣: あいまいな名前または意味のない名前
リスト 1 のコードには、短すぎる変数名、判読できない略語、およびメソッドの機能を反映していないメソッド名が含まれています。メソッド名が 1 つのことを実行することになっているという印象を与え、実際には別のことを実行する場合、誤解を招くため、重大な問題が発生します。
リスト 1. 悪い習慣: 曖昧または意味のない名前
<?php
function getNBDay($d){
スイッチ($d) {
ケース5:
ケース6:
ケース7:
1を返します。
デフォルト:
戻り値 ($d + 1);
}
$day = 5;
$
nextDay = getNBDay($day);
echo ("次の日は: " . $nextDay . "n")
;
優れた実践例: 記述的で簡潔な名前
リスト 2 のコードは、優れたプログラミング実践例を示しています。新しいメソッド名は非常に説明的で、メソッドの目的を反映しています。同様に、変更された変数名はよりわかりやすいものになっています。最も短い変数は $i だけであり、このリストではループ変数です。短すぎる名前を使用することに多くの人が眉をひそめますが、コードの機能が明確に示されているため、ループ変数での使用は許容されます (さらに有益です)。
リスト 2. グッド プラクティス: 説明的で簡潔な名前
<?php
定義 ('月曜日', 1);
定義 ('火曜日', 2);
定義 ('水曜日', 3);
定義 ('木曜日', 4);
定義 ('金曜日', 5);
定義 ('土曜日', 6);
定義 ('日曜日', 7);
/*
*
* @param $dayOfWeek
* @return int 曜日。1 は月曜日などです。
*/
関数 findNextBusinessDay($dayOfWeek){
$nextBusinessDay = $dayOfWeek;
switch($dayOfWeek) {
金曜日の場合:
土曜日の場合:
日曜日の場合:
$nextBusinessDay = 月曜日;
壊す;
デフォルト:
$nextBusinessDay += 1;
壊す;
}
$nextBusinessDay を返します。
}
$day = 金曜日;
$nextBusDay = findNextBusinessDay($day);
echo ("次の日は:" . $nextBusDay . "n");
?>
大きな条件を 1 つのメソッドに分割し、そのメソッドに条件を説明する名前を付けることをお勧めします。この手法を使用すると、コードの可読性が向上し、条件が具体化されるため、抽出して再利用することもできます。条件が変化した場合にメソッドを更新するのも簡単です。メソッドには意味のある名前が付けられているため、コードの目的が反映され、コードが読みやすくなります。
プログラミングを続ける前に、
問題を小さな部分に
分けて解決することに集中しやすくなります。緊急の問題を解決しながらプログラミングを続けると、関数はどんどん長くなります。長期的にはこれは問題ではありませんが、前に戻ってより小さな部分にリファクタリングすることを忘れないでください。
リファクタリングは良い考えですが、より短く、より焦点を絞ったコードを書く習慣を付ける必要があります。短いメソッドは 1 つのウィンドウで読むことができ、理解しやすいです。メソッドが長すぎて 1 つのウィンドウで読むことができない場合、アイデア全体を最初から最後まですぐに理解することができないため、従うのが難しくなります。
メソッドを構築するときは、各メソッドに 1 つのことだけを実行させる習慣を身に付ける必要があります。これは良い習慣です。第一に、メソッドが 1 つのことしか実行しない場合、再利用される可能性が高くなります。第二に、そのようなメソッドはテストが簡単です。第三に、そのようなメソッドは理解しやすく、変更しやすいからです。
悪い習慣: 過度に長いメソッド (実行する処理が多すぎる)
リスト 3 は、多くの問題を抱えた非常に長い関数を示しています。たくさんのことを行うので、十分にコンパクトではありません。また、読み取り、デバッグ、テストも簡単になります。ファイルの反復処理、リストの作成、各オブジェクトへの値の割り当て、計算の実行などが含まれます。
リスト 3. 悪い習慣: 長すぎる function
<?php
function writeRssFeed($user)
{
//DB接続情報を取得する
// ユーザーの設定を調べます...
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// クエリ
$perfsQuery = sprintf("SELECT max_stories FROM user_perfs WHERE user= '%s'",
mysql_real_escape_string($user));
$result = mysql_query($query, $link);
$max_stories = 25; // デフォルトは 25;
if ($row = mysql_fetch_assoc($result)) {
$max_stories = $row['max_stories'];
}
// データを取得しに行きます
$perfsQuery = sprintf("SELECT * FROM ストーリー WHERE post_date = '%s'",
mysql_real_escape_string());
$result = mysql_query($query, $link);
$feed = "<rss version="2.0">" .
"<チャネル>" 。
「<title>私の素晴らしいフィード</title>」 .
「<リンク> http://www.example.com/feed.xml </リンク>」 。
"<description>世界最高の飼料</description>" .
"<言語>en-us</言語>" .
"<pubDate>火曜日、20 10 月 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>火曜日、20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
「<ドキュメント> http://www.example.com/rss </docs>」 。
"<generator>MyFeed ジェネレーター</generator>" 。
"<managingEditor> [email protected] </managingEditor>" .
「<webMaster> [email protected] </webMaster>」 .
"<ttl>5</ttl>";
// フィードを構築します...
while ($row = mysql_fetch_assoc($result)) {
$title = $row['タイトル'];
$link = $row['link'];
$description = $row['description'];
$date = $row['日付'];
$guid = $row['guid']
$feed .= "<アイテム>";
$feed .= "<タイトル>" . $title "</タイトル>";
$feed .= "<リンク>" . $link .
$feed .= "<説明> " . $description >";
$feed .= "<pubDate>" . $date "</pubDate>;
$feed .= "<guid>" . $guid "</guid>";
$feed .= "</アイテム>";
}
$feed .= "</rss";
// フィードをサーバーに書き込みます...
echo($feed);
}
?>このようなメソッドをさらにいくつか記述すると、メンテナンスが非常に問題になります。
良い習慣: 管理しやすい関数固有のメソッド
リスト 4 元のメソッドをよりコンパクトで読みやすいメソッドに書き換えます。この例では、長いメソッドがいくつかの短いメソッドに分割されており、それぞれの短いメソッドが 1 つのことを担当します。このようなコードは、将来の再利用やテストに非常に役立ちます。
リスト 4. グッド プラクティス: 管理しやすい関数固有のアプローチ
<?php
function createRssHeader()
{
"<rss version="2.0">" を返します。
"<チャネル>" 。
「<title>私の素晴らしいフィード</title>」 .
「<リンク> http://www.example.com/feed.xml </リンク>」 。
"<description>世界最高の飼料</description>" .
"<言語>en-us</言語>" .
"<pubDate>火曜日、20 10 月 2008 10:00:00 GMT</pubDate>" .
"<lastBuildDate>火曜日、20 Oct 2008 10:00:00 GMT</lastBuildDate>" .
「<ドキュメント> http://www.example.com/rss </docs>」 。
"<generator>MyFeed ジェネレーター</generator>" 。
"<managingEditor> [email protected] </managingEditor>" .
「<webMaster> [email protected] </webMaster>」 .
"<ttl>5</ttl>";
関数
createRssFooter()
{
「</channel></rss>」を返します。
関数 createRssItem($title, $link, $desc, $date, $guid
)
{
$item .= "<アイテム>";
$item .= "<タイトル>" . $title "</タイトル>;
$item .= "<リンク>" . $link .
$item .= "<説明> " . $説明> ";
$item .= "<pubDate>" . $date "</pubDate>;
$item .= "<guid>" . $guid ."</guid>;
$item .= "</item>";
$item を返します。
関数 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'];
}
$max_stories を返します。
関数
writeRssFeed($user)
{
//DB接続情報を取得する
$settings = parse_ini_file("rss_server.ini");
// ユーザーの設定を調べます...
$link = mysql_connect($settings['db_host'], $settings['user'],
$settings['password']) OR die(mysql_error());
$max_stories = getUserMaxStories($link, 25);
// データを取得しに行きます
$newsQuery = sprintf("SELECT * FROM ストーリー WHERE post_date = '%s'",
mysql_real_escape_string(time()));
$result = mysql_query($newsQuery, $link);
$feed = createRssHeader();
$i = 0;
// フィードを構築します...
while ($row = mysql_fetch_assoc($result)) {
if ($i < $max_stories) {
$title = $row['タイトル'];
$link = $row['link'];
$description = $row['description'];
$date = $row['日付'];
$guid = $row['guid'];
$feed .= createRssItem($title, $link, $description, $date, $guid);
$i++;
} それ以外 {
壊す;
}
}
mysql_close($link);
$feed .= createRssFooter();
// フィードをサーバーに書き込みます...
エコー($フィード);
}
?> 長いメソッドを短いメソッドに分割することにも制限があり、過度の分割は逆効果になります。したがって、この良い習慣を悪用しないでください。コードを大きなチャンクに分割すると、長いコードを分割しないのと同じくらい読みにくくなる可能性があります。
コードにコメントを追加する
コードに適切なコメントを追加することは、コードを記述するのと同じくらい難しいように思える場合があります。コードが現在実行している内容に注釈を付ける傾向があるため、何を注釈付けするかを知るのは簡単ではありません。コードの目的をコメントすることをお勧めします。関数のあまり目立たないヘッダー ブロックでは、メソッドの入力と出力、およびメソッドの本来の目的について読者に説明されます。
コードが現在実行している内容をコメント アウトするのが一般的ですが、これは不要です。コードが複雑で、現在実行している内容をコメントアウトする必要がある場合は、コードを書き直して理解しやすくする必要があることが示唆されます。目的を説明するコメントを付けずにコードを読みやすくするために、適切な名前と短いメソッドを使用する方法を学びましょう。
悪い習慣: 関数のコメントの過剰または不足
リスト 5 のコメントは、コードが何を行っているか (ループの反復処理や数値の追加など) を読者に伝えるだけです。しかし、現在の仕事をする理由は無視されます。そのため、コードを保守している人は、コードを安全に (新たな欠陥を導入することなく) 変更できるかどうかがわからないままになります。
リスト 5. 悪い習慣: 関数のコメントが多すぎる、または不十分である
<?php
クラス ResultMessage
{
プライベート $重大度;
プライベート$メッセージ;
パブリック関数 __construct($sev, $msg)
{
$this->重大度 = $sev;
$this->メッセージ = $msg;
}
パブリック関数 getSeverity()
{
$this->重大度を返します。
}
パブリック関数 setSeverity($severity)
{
$this->重大度 = $重大度;
}
パブリック関数 getMessage()
{
$this->メッセージを返します;
}
パブリック関数 setMessage($msg)
{
$this->メッセージ = $msg;
}
関数 cntMsgs($messages
)
{
$n = 0;
/* メッセージを繰り返し処理します... */
foreach($messages as $m) {
if ($m->getSeverity() == 'エラー') {
$n++; // 結果に 1 を追加します。
}
}
$n を返します。
$
messages = array(new ResultMessage("エラー", "これはエラーです!"),
new ResultMessage("警告", "これは警告です!"),
new ResultMessage("エラー", "これは別のエラーです!"));
$errs = cntMsgs($messages);
echo("There are " . $errs . " error in the result.n");
?>
良い実践例: アノテーション付きの関数とクラス
リスト 6 のコメントは、クラスとメソッドについて説明します。目的。このコメントは、コードが現在のジョブを実行している理由を説明しており、将来コードを保守するときに役立ちます。状況の変化に応じてコードの変更が必要になる場合がありますが、コードの目的が容易に理解できれば変更は簡単です。
リスト 6. グッド プラクティス: アノテーション付きの関数とクラス
<?php
/**
* ResultMessage クラスは返されるメッセージを保持します
* プロセスの結果として、メッセージには重大度があり、
* メッセージ。
*
* @作者ナグッド
*
*/
クラスResultMessage
{
プライベート $重大度;
プライベート$メッセージ;
/**
* を割り当てることができる ResultMessage のコンストラクター
* 重大度とメッセージ。
* @param $sev {@link getSeverity()} を参照
* @param $msg
* @return 不明なタイプ
*/
パブリック関数 __construct($sev, $msg)
{
$this->重大度 = $sev;
$this->メッセージ = $msg;
}
/**
* メッセージの重大度を返します。1 である必要があります。
※「情報」「警告」「エラー」のいずれかです。
* @return string メッセージの重大度
*/
パブリック関数 getSeverity()
{
$this->重大度を返します。
}
/**
* メッセージの重要度を設定します
* @param $重大度
* @return void
*/
パブリック関数 setSeverity($severity)
{
$this->重大度 = $重大度;
}
パブリック関数 getMessage()
{
$this->メッセージを返します;
}
パブリック関数 setMessage($msg)
{
$this->メッセージ = $msg;
}
}
/*
* 配列内の指定された重大度を持つメッセージをカウントします
* メッセージの。
*
* @param $messages ResultMessage の配列
* @return int 重大度が「エラー」のメッセージの数
*/
関数 countErrors($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == "エラー") {
$matchingCount++;
}
}
$matchingCount を返します。
$
messages = array(new ResultMessage("エラー", "これはエラーです!"),
new ResultMessage("警告", "これは警告です!"),
new ResultMessage("エラー", "これは別のエラーです!"));
$errs = countErrors($messages);
echo("結果に " . $errs . " エラーがあります。");
>
エラー処理
一般的な経験則として、堅牢なアプリケーションを作成したい場合は、エラー処理の 80/20 ルールに従ってください。コードの 80% は例外と検証の処理に使用され、コードの 20% は実行に使用されます。実際の作業。これは、プログラムの基本ロジック (ハッピーパス) をコーディングするときによく行われます。これは、すべてのデータが利用可能であり、すべての条件が期待どおりである、内部で機能するコードを作成することを意味します。このようなコードは、アプリケーションのライフサイクル中に脆弱になる可能性があります。逆に、これまでに遭遇したことのない状況に対応するコードを記述するには、多くの時間がかかります。
この習慣では、すべてのエラーに対処するコードを作成するのではなく、十分なエラー処理コードを作成する必要があるため、コードが完了しません。
悪い習慣: エラー処理がまったく行われない
リスト 7 のコードは、2 つの悪い習慣を示しています。まず、特定の状態のパラメーターがメソッドで例外を引き起こすことがわかっているにもかかわらず、入力パラメーターはチェックされません。 2 番目に、コードは例外をスローする可能性があるメソッドを呼び出しますが、その例外は処理されません。問題が発生した場合、コードの作成者またはコードの管理者は、問題の原因を推測することしかできません。
リスト 7. 悪い習慣: エラー条件を処理しない
<?php
//
関数convertDayOfWeekToName($day)
{
$dayNames = 配列(
"日曜日"、
"月曜日"、
"火曜日"、
"水曜日"、
"木曜日"、
"金曜日"、
"土曜日");
$dayNames[$day] を返します。
echo("0 日の名前は
次
のとおりです: " .convertDayOfWeekToName(0) . "n");
echo("10 日の名前は次のとおりです: " .convertDayOfWeekToName(10) . "n");
echo("「オレンジ」の日の名前は次のとおりです: " .convertDayOfWeekToName('orange') . "n")
;
グッド プラクティス: 例外の処理
リスト 8 は、意味のある方法で例外をスローおよび処理する方法を示しています。エラー処理を追加すると、コードがより堅牢になるだけでなく、コードの読みやすさも向上し、理解しやすくなります。例外の処理方法は、メソッドを作成したときの元の作成者の意図をよく示しています。
リスト 8. グッド プラクティス: 例外の処理
<?php
/**
※曜日が無効な場合にスローされる例外です。
* @作者ナグッド
*
*/
class InvalidDayOfWeekException extends Exception { }
class InvalidDayFormatException extends Exception { }
/**
* 曜日を指定してその日の名前を取得します。
* 指定された値が範囲外の場合はエラーを返します。
*
* @param $day
* @return 不明なタイプ
*/
関数convertDayOfWeekToName($day)
{
if (! is_numeric($day)) {
throw new InvalidDayFormatException('値 '' . $day . '' は ' . $day . '' です。
'曜日の形式が無効です。');
}
if (($day > 6) || ($day < 0)) {
throw new InvalidDayOfWeekException('日番号 '' . $day . '' は ' . $day . '' です。
'無効な曜日です。0 ~ 6 が必要です。');
}
$dayNames = 配列(
"日曜日"、
"月曜日"、
"火曜日"、
"水曜日"、
"木曜日"、
"金曜日"、
"土曜日");
$dayNames[$day] を返します。
echo("0 日の名前は次のとおりです: " .convertDayOfWeekToName(0) . "n"
)
;
echo("10 日の名前は次のとおりです: " .convertDayOfWeekToName(10) . "n");
} catch (InvalidDayOfWeekException $e) {
echo ("値の変換中にエラーが発生しました: " . $e->getMessage() . "n");
}
試す {
echo("「オレンジ」の日の名前は次のとおりです: " .convertDayOfWeekToName('orange') . "n");
} catch (InvalidDayFormatException $e) {
echo ("値の変換中にエラーが発生しました: " . $e->getMessage() . "n");
確認
ですが
、パラメータを特定の状態にする必要がある場合は、メソッドを使用する人々にとって役立ちます。パラメータをチェックして、意味のある例外をスローする必要があります。
◆ 例外を可能な限り厳密に処理する 問題点生じるものは密接に関係しています。
◆各例外の専用処理。
コピーアンドペーストを使用しない
他の場所からコードをコピーしてコードエディターに貼り付けることができますが、これには長所と短所があります。良い点は、サンプルまたはテンプレートからコードをコピーすると、多くの間違いを回避できることです。欠点は、これにより、類似したプログラミング手法が多数発生しやすくなることです。
アプリケーションのある部分から別の部分にコードをコピーして貼り付けないように注意してください。このような場合は、この悪い習慣をやめて、このコードを再利用できるように書き直すことを検討してください。一般に、コードを 1 か所に置くと、変更する必要があるのは 1 か所だけになるため、後のメンテナンスが容易になります。
悪い習慣: リスト 9 の同様のコード スニペットは、
値が異なる、ほぼ同じであるいくつかのメソッドを示しています。コピーして貼り付けたコードを検索するのに役立つツールがあります (「参考文献」を参照)。
リスト 9. 悪い習慣: 類似のコード スニペット
<?php
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「Error」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countErrors($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == "エラー") {
$matchingCount++;
}
}
$matchingCount を返します。
}
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「警告」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countWarnings($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == "警告") {
$matchingCount++;
}
}
$matchingCount を返します。
}
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「Information」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countInformation($messages)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == "情報") {
$matchingCount++;
}
}
$matchingCount を返します。
$
messages = array(new ResultMessage("エラー", "これはエラーです!"),
new ResultMessage("警告", "これは警告です!"),
new ResultMessage("エラー", "これは別のエラーです!"));
$errs = countErrors($messages);
echo("結果に " . $errs . " エラーがあります。n");
?>
グッド プラクティス: パラメーターを使用した再利用可能な関数
リスト 10 は、コピーされたコードをメソッドに組み込む、変更されたコードを示しています。別のメソッドも変更され、タスクが新しいメソッドに委任されるようになりました。共通のアプローチを構築するには設計に時間がかかりますが、そうすることで直感的にコピー&ペーストするのではなく、立ち止まって考えることができます。しかし、共通のアプローチに費やした時間は、変更が必要になったときに報われます。
リスト 10. グッド プラクティス: パラメーターを使用した再利用可能な関数
<?php
/*
* 配列内の指定された重大度を持つメッセージをカウントします。
* メッセージの。
*
* @param $messages ResultMessage の配列
* @return int $withSeverity に一致するメッセージの数
*/
関数 countMessages($messages, $withSeverity)
{
$matchingCount = 0;
foreach($messages as $m) {
if ($m->getSeverity() == $withSeverity) {
$matchingCount++;
}
}
$matchingCount を返します。
}
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「Error」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countErrors($messages)
{
return countMessages($messages, "エラー");
}
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「警告」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countWarnings($messages)
{
return countMessages($messages, "警告");
}
/**
* の配列内で見つかったメッセージの数をカウントします。
* getSeverity() 値が「警告」の ResultMessage
*
* @param $messages ResultMessage の配列
* @return 不明なタイプ
*/
関数 countInformation($messages)
{
return countMessages($messages, "情報");
$
messages = array(new ResultMessage("エラー", "これはエラーです!"),
new ResultMessage("警告", "これは警告です!"),
new ResultMessage("エラー", "これは別のエラーです!"));
$errs = countErrors($messages);
echo("There are " . $errs . " error in the result.n");
>
結論
この記事で説明した良い習慣を身につければ、PHP コードを作成できます。読みやすく、理解しやすく、保守しやすいコードを構築できるようになります。この方法で構築された保守可能なコードは、コードのデバッグ、修正、拡張のリスクを軽減します。
適切な名前と短いメソッドを使用すると、コードの可読性が向上します。コードにコメントを付ける目的は、コードの理解と拡張を容易にすることです。エラーを適切に処理すると、コードがより堅牢になります。最後に、コードをクリーンな状態に保ち、再利用性を向上させるために、コピー&ペーストの使用をやめてください。