リーダブルコード(The Art of Readable Code)の読書ノートです。今回の記事では、コードの見た目を工夫するための基本的なポイントを紹介します。
コードの改善ポイント
1. コメントの整理
例えば、以下のようなコードがあるとします:
const wifi = new TcpConnectionSimulator(
500, /* Kbps */
80, /* millisecs latency */
200, /* jitter */
1 /* packet loss % */
);
const t3_fiber = new TcpConnectionSimulator(
45000, /* Kbps */
10, /* millisecs latency */
0, /* jitter */
0 /* packet loss % */
);
const cell = new TcpConnectionSimulator(
100, /* Kbps */
400, /* millisecs latency */
250, /* jitter */
5 /* packet loss % */
);
これを、次のように整理することで、コードの構造がより明確になります:
// TcpConnectionSimulator(throughput, latency, jitter, packet_loss)
// [Kbps] [ms] [ms] [percent]
const wifi = new TcpConnectionSimulator(500, 80, 200, 1);
const t3_fiber = new TcpConnectionSimulator(45000, 10, 0, 0);
const cell = new TcpConnectionSimulator(100, 400, 250, 5);
2. 列を揃えると、見えやすくなる
似たような構造を持つコードブロックがあると、このように整理することで、変数名と値の関係が明確になります。
// 変数をイコール揃えにする
const details = request.body.details;
const location = request.body.location;
const phone = request.body.phone;
const email = request.body.email;
const url = request.body.url;
3. 順序の一貫性を保つ
コードがあるところで A、B、C と書いていると、別の場所は B、C、A と書かないでください。アルファベット順や、処理実行の順など、何らかのルールを決めて従いましょう。デバッグにも楽。
悪い例:
const details = request.body.details;
const location = request.body.location;
const phone = request.body.phone;
const email = request.body.email;
const url = request.body.url;
// 同じ順番ではない
if (details) { record.details = details; }
if (phone) { record.phone = phone; } // locationはどこであるの?
if (email) { record.email = email; }
if (url) { record.url = url; }
if (location) { record.location = location; } // なぜlocationはここにあるの?
4. 宣言をブロックにまとめる
似たような処理の変数や関数の宣言をブロックにまとめましょう。
修正前 :
class FrontendServer {
constructor() {}
ViewProfile(request) {}
OpenDatabase(location, user) {}
SaveProfile(request) {}
ExtractQueryParam(request, param) return "";
ReplyOK(request, html) {}
FindFriends(request) {}
ReplyNotFound(request, error) {}
CloseDatabase(location) {}
}
修正後 :
class FrontendServer {
constructor() {}
// リクエストハンドラ
viewProfile(request) { /* ... */ }
saveProfile(request) { /* ... */ }
findFriends(request) { /* ... */ }
// リクエスト/レスポンス
extractQueryParam(request, param) { /* ... */ }
replyOK(request, html) { /* ... */ }
replyNotFound(request, error) { /* ... */ }
// データベース
openDatabase(location, user) { /* ... */ }
closeDatabase(location) { /* ... */ }
}
5. コードで段落分けを行う
複雑なロジックがある場合、同じ処理を空白行で区切ります。
修正前 :
function suggestNewFriends(user, emailPassword) {
const friends = user.friends();
const friendEmails = new Set(friends.map(f => f.email));
const contacts = importContacts(user.email, emailPassword);
const contactEmails = new Set(contacts.map(c => c.email));
const nonFriendEmails = new Set([...contactEmails].filter(x => !friendEmails.has(x)));
const suggestedFriends = User.findAll({ where: { email: Array.from(nonFriendEmails) } });
const display = {
user,
friends,
suggestedFriends
};
return render("suggestedFriends.html", display);
}
修正後 :
function suggestNewFriends(user, emailPassword) {
// ユーザーの友達のメールアドレスを取得
const friends = user.friends();
const friendEmails = new Set(friends.map(f => f.email));
// ユーザーのメールアカウントから全てのメールアドレスをインポート
const contacts = importContacts(user.email, emailPassword);
const contactEmails = new Set(contacts.map(c => c.email));
// まだ友達ではないマッチングユーザーを見つける
const nonFriendEmails = new Set([...contactEmails].filter(x => !friendEmails.has(x)));
const suggestedFriends = User.findAll({ where: { email: Array.from(nonFriendEmails) } });
// ページに表示
const display = {
user,
friends,
suggestedFriends
};
return render("suggestedFriends.html", display);
}
6. コードの一貫性を重視する
例えば、クラスの括弧の位置について、以下の2つの書き方があるとします:
class Logger {
};
// または
class Logger
{
};
「正しい」スタイルよりも、一貫性の方が重要です。
チームで開発する場合、どちらかの書き方を選んで、それに従うことが重要です。スタイルを混在させると、コードの読みやすさが下げます。コーディングスタイルを統一しよう!
所感
ある程度デザインと同じね