21
2019

関数名でよく使う英単語とニュアンス

CATEGORY開発全般
最近またコードレビューでGetXxxと言いながら更新してる関数を見かけたのでorz、何番煎じか分からないけど、関数名(メソッド名)によく使う英単語とそのニュアンスをまとめてみる。
なお、以下は俺の感覚なので、人によって違うというのはもちろんあると思うし、またフレームワーク等で命名規則が定まっている場合はそちらが優先なので、念のため。

Get
データを取得する。かなり汎用な語句で、データ取得全般に用いられる。オブジェクトのプロパティを取得するgetterのイメージも強い。そのためか、処理にコストがかからず、またデータを書き換えるといった副作用が無いイメージが強い。

データ取得ではあるが、上記の理由からDB検索などではGetを用いることは少ない(代わりにFind等を使う)。一方で、Key-Valueストアへの参照ではGetが使われることも多い。また、動的に戻り値を生成するような処理に使われることもあるが、こちらは別の単語(Make等)で区別するケースも多い。

英単語としての "get" は幅広い意味を持つが、プログラム上では上記のイメージが極めて強いため、データ取得以外の意味で用いてはならない
Set
データを設定する。Getの対になる単語だが、こちらはそこまで汎用的には用いられない。プロパティを設定するsetterや、また何かフラグを立てたりといった用途のイメージ。

データ設定であるが、同じくDB更新には用いられない(ただしDBにフラグを立てるなどはありえる)。一方でこちらもKey-Valueストアへの保存では用いられることも多い。
Is
bool値を返す処理。これもかなり汎用な語句で、単にgetterのbool版として用いられることもあれば、最終的にbool値を返す大きな関数に使われていることもある。副作用は無いイメージ。

なお、Isは英語の疑問文由来なので、前後の文脈によってはIs以外になるケースもある筈だが、日本人にはよく分からないのでたいてい全部Isになる。
Update
データを更新する。同じくかなり汎用な語句で、データを更新する処理全般で用いられる。DBのUPDATE文のイメージから、モデルやリポジトリにある場合は、UPDATE文を流す処理だとも感じる。

Updateなので、新規データ作成のイメージではない。新規作成であることが明確な場合は、後述のCreate等と使い分ける。
Check
何かをチェックする。汎用的な語句だが、目的が分かり辛いことから批判されることが多く、今日ではあまり見かけない。
Find
データを取得する。Getと比べて、リストからデータを取ってきたりと、何かを探索するイメージ。DB検索で使われることが多い。
Select
データを取得する。あまり見かけない?モデルやリポジトリでDBにSELECT文を流す処理に付けられることも。Findよりも低レイヤーな印象。
Search
データを検索する。Findと比べて、より検索の意図が強いものに付けられる印象。
Create
データを新規作成する。新しいインスタンスの作成時や、文字列の生成などで広く用いられる。モデルやリポジトリにある場合は、DBへのINSERTが行われるイメージも。
Make
データを新規作成する。これも新規作成だが、DBへのINSERTは含まれないイメージ。Createよりも何かを構築する的な感じ?
Build
データを新規作成する。こちらはさらにデータを構築する感が強まっている。条件からインスタンスを生成するとかそういう用途が多い?
New
データを新規作成する。これはもう純粋にインスタンス生成用の関数とかに限られる。
Insert
データの挿入。DBへのINSERTや、配列への挿入などに限られる。
Generate
データを新規作成する。こちらは、乱数や連番の生成や、何かを生み出すような、そんなイメージ。
Save
データを保存する。保存の方法を問わない感じだが、Rails系(?)のSaveがCreate or Updateなので、その印象が強い。
Load
データを読み込む。他の参照系と異なりLoadだと自分に読み込むイメージ?なのであまり使うことは無い。むしろライブラリの読み込みとかで使うことの方が多い印象。
Delete
データを削除する。汎用的で、プロパティ等の削除からファイルの削除、DBでのDELETEまで、何でも使われる。
Destroy
データを破棄する。Deleteと大体同じだが、要らなくなったデータを破棄するようなイメージがある?
Remove
データを取り除く。こちらは配列やマップ、DBから値を除去する場合に用いられるイメージ。
Reset
データをリセットする。データを初期値に戻したりする場合に使われるイメージ。その過程で削除されることもあるが、削除とはちょっと違う。
Init / Initialize
初期化する。こちらは何もない状態から、最初に初期化する感じ。初期設定とか初期データ作成とか。
Copy
データをコピーする。データを別のオブジェクトにコピーしたりとか。
Clone
インスタンスをクローンする。インスタンス等を完全に複製する場合はこちら。普通のコピーの意味で使うべきではない。
Add
データを加える。汎用的で、数値を加算することもあれば、配列に値を追加するとか、追加全般に用いられる。ただし、DBに保存するイメージは無い。
Append
データを加える。Addと違って、文字列の後ろに付け足すみたいな用途に限られる。
Replace
置換する。文字列の一部を書き換えたり、オプジェクトの特定の値を上書きしたり、とか。
Increment
加算する。数値をプラスするときに用いられる。リポジトリなんかの場合、DBを更新する場合もある。
Decrement
減算する。Incrementの逆。用途も同じ。
Count
データを数える。配列の長さを数えたり、DBの行数を数えたり。
Sum
データを合計する。配列の値を合計したり、DBの値を合計したり。
Calc / Calculate
計算する。純粋に計算するだけの関数とかで使うイメージ。
Filter
データに割り込む処理全般。渡された値を何か加工したり、またフィルタリングして取り除いたりする。ただし、汎用的すぎるので、後者の用途ではInclude/Excludeを使うことが推奨されている。
Include
データを特定の条件を満たすもののみにする。配列を条件を満たすもののみに絞り込むとかそういうイメージ。
Exclude
データを特定の条件を満たさないもののみにする。Includeの逆。
Contain
データを含むか。配列に値が含まれるかとかに用いられるイメージ。
Has
データを持つか。オブジェクト自分自身がプロパティを持つかのようなイメージ。
Open
何かを開く。コネクションを開くとかそういうイメージ。
Close
何かを閉じる。Openしたものを閉じるのに用いられる。
Start
処理を開始する。バッチ処理の実行や、非同期処理の開始などに用いられるイメージだが、単に一連の処理の実効的なニュアンスで使われることもある。
Stop
処理を停止する。実行中の処理などを中断する。一時停止なこともあれば、処理の打ち切りのことも。
Cancel
何かを取り止める。実行中の処理の取り止めや、GUIのキャンセルボタンのように処理せず終了的なイメージ。
Run
処理を実行する。一連の処理を実行するようなイメージ。
End
処理を終了する。処理が終了するときの処理で使われるイメージ。
Invoke
処理を実行する。普通の関数に使うことは少なく、リフレクションとか、継承とかで別の関数を実行させるような関数で使ったりするイメージ。
Exec / Execute
処理を実行する。Invokeに近いが、普通の関数で使うことも?また外部コマンドを実行する場合にも用いられるイメージ。
Do
処理を実行する。実行の意味だが、一転してこちらは普通の関数で用いられるもの。適切な動詞が無い時とかに付ける?
Format
データを成型する。文字列を特定の書式にするとか、JSONのデータ構造を整えるとか、そういうイメージ?
Out / Output
データを出力する。標準出力だのファイルだのレスポンスだのストリームだのに出力するイメージ。
Wrire
データを書きこむ。ファイルやストリームに書きこむイメージ。
Read
データを読み込む。ファイルやストリームからデータを読み込むイメージ。
Flush
データを吐き出す。バッファに残ったデータを出力したりというイメージ。
Render
画面をレンダリングする。画面の表示内容を生成したりというイメージ。レスポンスでHTMLを返す場合にも使われる。
Config / Configure
設定する。ライブラリに設定したり、ユーザーの設定を保存したり、何かしらの設定を行う。

仕事してて普通に出てくる単語をざっとまとめてみたけど、こんな感じか?似た言葉でもニュアンスが微妙に違ったりするのでご注意を。
よく分からない人は、とりあえず Get, Set, Is, Update 辺りを使い分けるところからスタートで。

補足1) 特定の単語じゃ表現できない場合

プログラムを書いていると、関数が肥大化して、これらの単語じゃ機能が表現しきれない、ってことは往々にしてある。そういう場合にどうすればよいのかという補足。

例えば、DBからユーザー情報を取得すると同時に、DBのログイン日時を更新する関数があるとして…
  1. 別々の関数に分割する。
    例) GetUser() と UpdateLastLogin()
  2. 関数名を上位概念に置き換える。
    例) Login()
  3. 関数名に複数の語句を入れる。
    例) GetUserAndUpdateLastLogin()
といった対応が考えられる。
推奨されるのは1か2。そもそも関数に複数の機能が含まれるのがNGという話なので、分割するか、上位概念の関数に纏めるのが正攻法となる。
が、分割は性能的な理由などで出来なかったりするし、上位概念と言われても日本人には適切な用語を考えるのは難しかったりする。
なので、自分は致し方なく3にすることも割とある。

なお、上記いずれの解決策も取れない場合は…せめてコメントをちゃんと残しましょう。
関数名を変えると影響が広すぎるとか、どうしようもないケースは往々にある。推奨しないが、せめて注意書きだけはきっちり残そう(--;

補足2) どこまでが関数の機能なのか

関数の機能というが、どこまでを含めるのかという話。例えば、以下のようなgetUser関数があったとする。
function getUser($id) {
if ($user = Cache::getUser($id)) {
return $user;
}
DB::init();
$user = DB::findUser($id);
Log::info("userId={$id} accessed");
Cache::setCache($id, $user);
return $user;
}
この関数は内部的にDB接続したりキャッシュを更新したりログを出力していたりするが、これはgetUserで良いと感じる。なぜなら、それらの処理はこの関数の目的とは直接関係ない、システム的な話だから。
この関数は仕事としては、getUserしかしていないと感じるから。

一方で、ありえないと思うが、例えばこの関数をこんな風に使ってはいけない。
// DB接続初期化(getUserを呼ぶとDBに接続できる)
getUser();
いろいろ論外なのは置いておくとして、DB接続という目的が関数の機能として外に出るのであれば、getUser以上のことをしているので、この名前は不適切である。

もちろん、これは極端な例だけれど、ソースが改修改修でスパゲティ化していく過程で、関数が目的外に使われてしまう事例もあるので、注意されたし。


以上、だいぶ長くなったが、名付けは良いプログラムを書くための第一歩なので、気を付けましょうということで。
スポンサーサイト



Tag: プログラミング

0 Comments

Leave a comment