見た目、
えっ? いつも適当に付けてるから、
おいおい……そういうのは良くないな。プログラミングの半分は設計で残り半分は名前付け、
そ、
名前が付いていない条件に名前を付けたり、
そう言われると、
複雑な条件には名前を付けよう
if文などで条件式を書くとき、
条件式を別の関数に分ける
たとえばJavaScriptにおいて、
- JPEG
- JPG
- jpeg
- jpg
またPNGファイルと判断する拡張子は次の2種類とします。
- PNG
- png
これを素直に書くとリスト1のようになります。しかし、
function doSomething(fileName) {
var extension = getExtensionFromFileName(fileName);
// 条件式が長すぎて読みづらい
if (extension === "JPEG" ||
extension === "JPG" ||
extension === "jpeg" ||
extension === "jpg" ||
extension === "PNG" ||
extension === "png") {
// ファイルに対して処理を行う
}
}
そこでリスト2のように、isJPEG
、isPNG
と名前を付けて、isJPEG()
やisPNG()
の詳細は知らなくても、
// JPEG ファイルの判別をisJPEG() として抽出する
function isJPEG(extension) {
return (extension === "JPEG" ||
extension === "JPG" ||
extension === "jpeg" ||
extension === "jpg");
}
// PNG ファイルの判別をisPNG() として抽出する
function isPNG(extension) {
return (extension === "PNG" ||
extension === "png");
}
function doSomething(fileName) {
var extension = getExtensionFromFileName(fileName);
// 条件式がシンプルになり読みやすくなる
if (isJPEG(extension) || isPNG(extension)) {
// ファイルに対して処理を行う
}
}
変数を使用する
真偽値を返す関数であっても、
例として、g_
という関数を見てみます。この関数は指定したファイルの中身を取得するための関数で、g_
は真偽値が返される仕様であるため、
if (!g_file_get_contents(file_name, &contents,
&length, &gerror)) {
/* エラー処理 */
}
しかしg_
は4つも引数を取るため、
また、g_
の仕様を知らない人がこのコードをデバッグしようとしたとき、
さらに言えば、
このような場合には、g_
の戻り値を一度succeeded
という名前の変数に代入するとよいでしょう。この関数の仕様を知らない人にとっても、
gboolean succeeded = g_file_get_contents(file_name,
&contents,
&length,
&gerror);
if (!succeeded) {
/* エラー処理 */
}
条件には真偽型であることがわかる名前を付ける
先ほどの例でも見たように、
- available
(利用できる)、 downloadable (ダウンロードできる) のような具体的な状態を表す形容詞 - connected
(接続された)、 succeeded (成功した)、 failed (失敗した) のような具体的な動詞の受動態 - is、
has、 can、 shouldなどの接頭辞を伴ったhasAttributeやisPNGのようなフレーズ
Rubyのメソッド名においては、connected?
のように名付けるという慣習もあります。
たとえば、getConnectedStatus()
という名前であったことがありました。この関数は真偽値を返す関数で、
if (getConnectedStatus()) {
/* 接続状態の処理 */
} else {
/* 切断状態の処理 */
}
しかし、getConnectedStatus()
という名前からは、
このときはリスト7のように、is
を付け、Status
を外して、isConnected()
という関数名に変更しました。これは状態を取得する関数での話ですが、connected
という1単語にしてもよいでしょう。
if (isConnected()) {
/* 接続状態の処理 */
} else {
/* 切断状態の処理 */
}
適切な長さの名前を付けよう
プログラムを書いていると、
名前は、
とはいえ、
短すぎる名前、長すぎる名前
良いコードの書きかたについて語られる場面では、
getSs: function() {
var a = MailServices.accounts;
var ss = a.allServers;
var r = [];
for (let i = 0, m = ss.length; i < m; ++i) {
let s = ss.queryElementAt(i, Ci.
nsIMsgIncomingServer);
if (s.type == "none")
continue;
r.push(s);
}
return r;
},
気づいた人もいるかもしれませんが、ss
って何だ? 代入文を調べると……ああ、getSs
って何だ? ……ああ、
では、
thunderbirdAddonCollectServersArrayToBeAuthenticated: function() {
var thunderbirdAccountManagerService = MailServices.accounts;
var allThunderbirdServerObjectsArray = accountManager.allServers;
var returnedFoundThunderbirdServerObjectsArray = [];
for (let index = 0,
maxIndex = allThunderbirdServerObjectsArray.length;
index < maxIndex; ++index) {
let thunderbirdServerObject = allThunderbirdServerObjectsArray
.queryElementAt(index, Ci.nsIMsgIncomingServer);
if (thunderbirdServerObject.type == "none")
continue;
returnedFoundThunderbirdServerObjectsArray
.push(thunderbirdServerObject);
}
return returnedFoundThunderbirdServerObjectsArray;
},
余白が少なくて、
文脈に基づいて名前を付けよう
名前が短すぎたり長すぎたりするのは、
文脈とは、
文脈の中ですでに説明されていることまでもが名前に含まれていると、Array
クラスのインスタンスであることは自明ですし、Object
クラスのインスタンスであることも自明です。また、localization
やauthentication
のような長い単語の中には、l10n
やauth
のように省略することのほうが多い単語もあります。
その一方で、allServers
とfoundServers
のように残してよいでしょう。このように、
文脈に基づいて名前を付けなおした例がリスト10です。過不足なく情報が盛り込まれているため、
collectAuthServers: function() {
var accountManager = MailServices.accounts;
var allServers = accountManager.allServers;
var foundServers = [];
for (let i = 0, maxi = allServers.length; i < maxi; ++i) {
let server = allServers.queryElementAt(i,
Ci.nsIMsgIncomingServer);
if (server.type == "none")
continue;
foundServers.push(server);
}
return foundServers;
},
文脈上明らかなら、1文字変数も使ってよい
文脈の中に説明が含まれていないにもかかわらず、Array
クラスのsort
メソッドの比較関数における仮引数名などは、
リスト11は、aServer
やbServer
のように無理にそれ単体で意味のある名前を付けるのはかえって冗長です。
servers.sort(function(a, b) {
if (a.hostName > b.hostName)
return 1;
if (a.hostName < b.hostName)
return -1;
return 0;
});
forループにおけるカウンタ変数も、
このように、
良い名前付けと良い設計は表裏一体なんだ。良い設計なら自然と良い名前を付けられるし、
うーん、
そういうのは登場人物が足りないんだ
ね。

なるほど! 名前付けに困ったときは、