命名にWhatやHow以外を付けるスタイル
あくまでもスタイルなのですが、メソッドやクラス名にWhatやHow以外をつけると便利、という話です。
命名は短く簡潔にとはいうけれど
ざっくりなんですが
$user->delete()
みたいなメソッドがあったとき、「ユーザーが削除されるんだろうな」という期待があります。
このとき、要件として、「管理者ユーザーは削除できない」という要件が追加されたとしましょう。そのときにいくつか人が取り得るパターンがあるように思います。
継ぎ足しパターン
// 外部でチェックして削除するパターン
if(!$user->isAdmin()) { $user->delete(); }
おそらくこれが後づけの要件では一番良くあるパターンです。
これの怖い所はこの確認を忘れると事故になる事です。確認は必須なのに、補完にたよったり、コピペしているとうっかりこのif判定を忘れるパターンがあります。なので私は安全ではないと思っています。
「安全に削除する」メソッドを足すパターン
// 内部的に安全か確認して、分岐するパターン
$user->safeDelete();
// 削除は削除なので、こちらはそのまま削除ができてしまう
$user->delete();
チェックして削除するメソッドを作成し、そちらを使うパターンです。
これは結構安全です。が、引き続きまちがえてdeleteをつかってしまう可能性が残ります。
なぜならdeleteというのは一般的な単語なので、ぱっとみてそれがどれくらい危険なのかがわかりにくいからです。
コピペ元がsafeをつかっていればいいんですが。一般的な名称の方が危険というのは解りづらい時があります。
素直な名称は安全側にもちいて、危険なメソッドは特別な名前を付けるパターン
// 管理者は削除できない
$user->delete();
// 管理者を削除するにはForceDeleteする必要がある
$user->forceDelete();
私はこのような名称を推奨します。
コードを書いていて「forceDelete…怖いななんだこれ?」と気づける余地を残すという事です。
応用
DTO等でも同様のことが言えます
- UserProfile => あくまでも外部に見えても良い情報しかいれない
- UserProfileWithCredential => 例えばパスワードのハッシュ値や、メアドや、漏洩してはマズい情報まで入っているDTO
普通にコードをかいていて後者をどこででも使おうと言う人は居ないでしょう。居ないでしょう、といいいつつ、一般的なDTOで、ユーザーの情報を全部カラムに追加するタイプのActiveRecordパターンだと、「自覚はせずに」そうしているパターンもありますが…
応用2
また、上ほどあからさまでないとしても、機能名が「安全か、安全でないか」が命名からわかりにくいことがあります。
例えば EntryList などというEntryのリストがあるとします、これは安全ですか?安全じゃないですか?
自分の管理画面で使われるEntryListは非公開エントリなどが含まれることもあるでしょう。しかし、公開画面でもEntryListという名前は使われるでしょう。なので、以下のような名前が適切だと私は思います
- PublicEntryList
- PrivateAndPublicEntryList (イマイチな名前になってしまったが、つまりはAllなどはダメである)
これはDTOとして持つ中身は一緒かもしれません。しかしPHPなどでは引数に型が指定できますし、Instanceofで判定できるので、「危険かどうかをクラス名につける」のは安全なコードを書く事につながります。
怖いことは
「表示してはダメなデータであっても偶然うごいちゃう」ことです。
プログラマは多くの場合、うごくと満足しがちです。そしてテストをかいても、このコードは別に規約に違反していません。
なので、あえて命名にこだわって安全側にたおし、危険なものに気づけるというのは有用なのです。
コードは書くのは一瞬ですが、読むのは(サービスの)一生です。
まとめ
- コードはコピペされる、自分でも忘れることもある
- メソッドやクラスは危険な行動や行為をするときも、しないときもある
- 名前を別けるときは、危険な方に特別な名前を付ける
Discussion