もういっそお父さんとお母さんの名前から1文字ずつ取ってつけたいと思ったのは私だけではないはず。

良いクラス名(あるいはそれと同じ役割のモジュール名等)やメソッド(関数)名をつけるときに迷っている新人エンジニアさん達をよく見ます。私も昔はなんどもなんども名前を書いては消しを繰り返していたものです。そんな地味に難しい命名ですが、良い名前をつけるのが得意な人たちは一体どうしているのでしょうか?実は名前のつけ方についてはオブジェクト指向に毒されているエンジニアの間では、ある程度共通のパターンが存在しています。今回はそれを紹介します。

良い命名をしなければならない理由

そもそもなんでこんなややこしいことを必死で考える必要があるのでしょうか?さっさと作ってしまう方がよほど生産的なように思えてしまいますよね。理由としてよく語られるのは「他の人が理解しやすいようにするため」というものがあります。これはすごく大切なことではありますが、個人的にはこれだけでは不十分に感じています。そこで私はいつももう1つ別の理由を加えて説明しています。良い命名をするもう1つの理由はソースコードを変更に強い堅牢なものにすることだと考えています。実は良い命名をすることによって変更に強く壊れにくい識別子を得ることができ、開発のコストを抑ることができるのです。

使う側から見た役割で命名する

これはクラスとメソッドで共通する最も重要な命名方法です。命名対象のクラスやメソッドが、それらを使う側(呼び出し元)から見て何をしてくれるかという視点を利用します。なぜこれが最も重要なのかというと、使う側の視点で命名することで、命名対象のクラスやメソッドの実装の詳細(あるいは内部構造)を呼び出し元から隠蔽することができるからです。より詳しく説明すると、そのクラスやメソッドにどのような処理が書かれているか、どんな型のデータを保持しているかといったことに、呼び出し元を依存させないようにできます。いわゆるカプセル化の考え方を命名にも適用しているのです。

具体的な例を使って説明します。
社内用のWebアプリケーションで、特定の処理を行う際にその処理が行われたことを他のユーザにチャットツールで通知する必要があったとします。ただし、チャットツールは特に何を使ってもかまわないとします。
まずは使う側の視点を使わない例を示します。社内ではたまたまチャットツールとしてHipChatを使っており、HipChatに通知するAPIを利用するためのクラスとしてHipChatMessenger(HipChatに伝言してくれる者)クラスを作ったとします。HipChatのAPIを使うことでこのクラスは実現されており、命名の意図としては「これがHipChatと連携する部分ですよ」と説明するためにクラス名にHipChatという用語を含ませています。よく見る命名方法ですが、これはあまり良い命名ではないです。例えば、あるタイミングでHipChatからSlackへ移行することになったとします。その場合、HipChatMessengerの実装を変更することになります。そうなるとHipChatMessengerという名前に矛盾が生じますよね?HipCahtMessengerSlackMessengerに名前を変更する必要があります。クラス名を変更すると、呼び出し元にも変更の義務が生じてしまいます。HipChatについて何も責務を持っていない呼び出し元にもチャットツールの変更に伴う影響が出てしまうのです。
上述したことを回避するためには使う側の視点を使い、単にMessenger(伝言してくれる者)という名前をつけてみましょう。こうすればチャットツールが変更になっても命名に矛盾は生じず、呼び出し元に変更の影響を伝搬させることもありません。
ただし、チャットツールがなんでもよいではなくHipChatであることが重要であるような場合はHipChatであることを明示することの方が重要になるので注意しましょう。

メタファを使う

現実世界に実際に存在している物や概念の名前をつける方法です。例えば、本の貸し出し状況を取得するメソッドや、指定した本を登録済みのユーザに貸し出すメソッドを提供するようなクラスであればLibrary(図書館)といった名前をつけるようなことがこれに当たります。
メタファを名前にすると直感的に役割がわかりやすくなります。また、現実世界に存在している物や概念は基本的には変化することがあまりなく、そこからつけられた名前もまた壊れにくく堅牢なものになります。

ドメインの用語を使う

作成しているプログラムが解決しようとしている問題領域(ドメイン)に登場する用語をそのまま名前にすると良いでしょう。ドメイン駆動設計ではまさにこれが推奨されているかと思います。理由は先ほどのメタファと同様です。ドメインの用語を使うこともまた、ドメインに存在する概念や物をメタファとした命名に等しいです。

パターンの名前を使う

GoFのデザインパターンのパターン名等から名前の一部を拝借してくるのも場合によっては有効です。この命名方法はエンジニア同士で非常に共通認識が取りやすいというメリットもあります。例えば、タスク管理ツールのタスクを生成するクラス名をTaskFactoryクラスとしておけばTaskクラスのインスタンスを生成するのに特化したクラスだと一目でわかります。パターン自体がそもそもメタファになっているため、ドメインに存在しない処理を担う場合や適切なメタファが存在しない場合には結構使えます。

最後に

命名で最も重要なのは使う側の視点です。実装の詳細よりも1段抽象的な捉え方をすることで理解しやすく、変更につよい名前をつけるように心がけて見てください。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.