Help us understand the problem. What is going on with this article?

【極論】クラス名ではいかなる接尾語も禁止!!

クラス命名のアンチパターンについては、世間でも問題意識が共有されていて、すでに記事が書かれているのですが(Qiitaならこの記事 など)、

私は正直「これは負け戦なのでは?」と感じていました。ダメな命名パターンは無数にあり、リストは長くなる一方だからです(そして長すぎるリストは読まれない)。

そこで戦況を巻き返すべく、無茶を承知でこう宣言させていただきます。

ルール「クラス名ではいかなる接尾語も禁止」

何らかの接尾語(サフィックス)が付いたクラス名は全てNGです。

Service, Manager, Controller, Filter, Handler, Validator, Visitor, Agent, Dao, Rule, Info, Data, Helper, Util, Type, Enum, Proxy その他とにかく接尾語(サフィックス)は悪いものです。命名を考え直してください。

また、Reader, Writer, Accessor, Getter, Fetcher などの「動詞-er/-or」も接尾語の一種だと思ってください。「動詞-er/-or」も悪です。

※例外条項

  • フレームワークやプロジェクトに接尾語のルールがある場合はそれに従います。
  • (上級者向け)接尾語を新設するときはREADMEやコメントに明記します。

なんで接尾語はダメなの?

経験上、こういったクラスはえてして、とりあえずメンバやメソッドをぶち込む掃き溜めになるからです。

  • Userに関係する情報だからとりあえず UserInfo のメンバにしよう」とか
  • Userに関連する処理だからとりあえず UserService の静的メソッドにしよう」とか

また、接尾語がつく名前は、深く考えずにクラスを設計してしまっていることや、不適切なクラス分割をしてしまっている事が多いです

なんで接尾語はダメなの?その2

また、同じ接尾語が付くクラスは、共通性を持つと期待するのが人情です。例えば HogeValidatorFugaValidatorがあった時は、

  • それぞれ Hogeオブジェクトと Fugaオブジェクトをチェックするんだろう
  • 同じメソッド(多分 validate)を提供するんだろう
  • 生成方法(new なり DI なり)も同じだろう
  • Piyo クラスを新設した時は、PiyoValidatorも必要なのかな?

と期待するでしょう。

しかし、こういった接尾語・カテゴリを正しく設計するのは案外難しいことです。

例えば一時期Rails界隈では「〜Service」が流行ったのですが、現在は下火です。最初は良いアイデアだと思われたのですが、実践してみると酷いコードが生まれる事も多かったからです。

じゃあ、どうやって接尾語を消せばいいんだよ!?

接尾語を避ける方法はいくつかあります。

1. そもそもクラスを作らない
UserInfoUserUtilのメソッド・メンバは Userに移せるはずです。
その結果 Userクラスの行数は大きくなりますが、気にする必要はありません。いわゆる「クラスの肥大化」「Fat Model」は本当に大規模なコードでのみ問題となります。

2. クラスを細かく分ける
例えば、User関係のチェックが詰め込まれたUserValidatorがあるとしたら、チェック項目ごとにクラスを分けます。

  • User::NameIsNotEmpty
  • User::EmailAddressValid
  • User::AdultAge

etc...

3. 見方を変える
例えば、「ネットワーク越しにユーザーログを書き込むクラスNetworkUserLogWriterでログを書き込む」ではなく、「ユーザーログUserLogにログを書き込む(実際の処理はネットワーク越しに行われる)」のだと考えてみてください。

ログを生成する側(ControllerとかModelとか)からすれば、とにかく抽象化されたナニモノカにログを書けることが大事で、それが「ネットワーク越しに」「書き込んでいる」ことは重要ではありません。隠蔽されていて良いのです。隠蔽されるべきことを名前で表す必要もありません。

4. いっそオブジェクト指向を諦める
どうしても的確なクラス名が思いつかなかったり、既存のコードが既に破綻していてクラス設計は無意味な場合があります。そんなときは、オブジェクト指向を諦め、クラス・メソッドではなく、純粋な関数にしてしまう手もあります。

「関数」が無い言語も「staticメソッドを1個だけ提供するクラス(クラス名はstaticメソッド名と同じ)」などで同じ事ができます。

接尾語は絶対にダメですか?

もちろん、人気のフレームワークが提供する「接尾語」(RailsのControllerなど)は、長年の風雪に耐えたものであり、使ってもなんら問題ありません。プロジェクトで DDD / Clean Architecture を実践するつもりなら、RepositoryUseCaseといった接尾語を使うことになるでしょう。

あなたが本当に必要だと思うなら、新たな接尾語を新設しても構いません。ただし、その際には以下に注意してください:

  • 接尾語が的確であること(Serviceの二の舞を避ける)
  • 接尾語が実際に必要であること(今回の1クラスだけで終わるんじゃないか?)
  • 接尾語の使い方をREADMEやコメントで説明する事

接尾語以外にもダメな命名はあるよね?

もちろんです。

  • 英語ではなく、ローマ字ですらない(UserRegistKubunとか)
  • 名前が内容に反する(ViewModelなのに、DBを更新するだと!?)
  • Common (大抵雑多なメソッドの掃き溜めになる)

など、まだまだありますが、私にはその元気がありません。他の誰かが書いてくれることを望みます。

また、正しい名前を付けることは大切ですが、それは当たり前のことであって、プログラムが動き、人の役に立つ事が重要なのは言うまでもありません。

どっとはらい。

tonluqclml
エムスリーでソフトウェアエンジニアしています。仕事ではRubyもScalaもPythonもBashもなんでもやる雑食系。 Twitter:https://twitter.com/doloopwhile 昔の個人ブログ:http://doloopwhile.hatenablog.com/ 勤務先ブログ: https://www.m3tech.blog/
http://doloopwhile.hatenablog.com/
m3dev
インターネット、最新IT技術を活用し日本・世界の医療を改善することを目指します
https://m3.recruitment.jp/engineer/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした