最近卒業制作に追われる中でとてもいい命名法を編み出したので、広大なネットの海から意見をもらいたい。
忙しい人のための「現実見ろよ法(仮)」
- 機能を現実に存在するものに置き換えて命名しろ
- この命名法で命名できない場合それはたぶん設計が間違っている
【 Unityでプレイヤーキャラを作る場合の例 】
■ → ゲームオブジェクト
● → コンポーネント
■ Player
● Head (入力やゲームからのフィードバックから各コンポーネントを制御)
● Body (体力やスタミナの管理を担当)
● Arm (攻撃を担当)
● Leg (移動を担当)
● Bag (持ち物管理を担当)
● Armor (防御力を管理)
要するに「CharacterMove」とか「InputManager」みたいなコンポーネントを作るなって話
暇人のための詳説
現実のものに即した命名をしようという考え方である。
虚ろを覗いてばかりいるプログラマーたちはイキって抽象的な名前を付けたがる。
「Manager」とか「Update」とか。
そういうのはやめて現実にあるもので命名しよう。
なぜ CharacterMove がダメなのか
機能の分割, 追加, 変更 etc. するときに困るから。
CharacterMove は「キャラクターが動く」という処理を表した名前と思われる。
しかし「処理」を名前にするのはよろしくない。
人間の頭は非可算なものを効率よく分割できるように設計されていない。
リスト等で複数個まとめて管理するとき変数名に困る
- CharacterMoves にはしたくない
- じゃあ CharacterMoveManager にするか!(地獄の始まり)
オブジェクト指向って「モノ」をいっぱい集めてデカいもの作ろうぜ!って思想なので、
そもそも不可算な名前を付けてる時点でだめだと思う。
機能を分割すると名前が長くなる
- CharacterMoveGroundNormalChecker って何?
- 概念を分割しても所詮は概念なのでさらに機能分割するとどんどん悲惨なことになる
概念は分割したところで所詮は概念なので、実態を持つ「オブジェクト」に昇格することはない。
よくエンジニアはろくろを回しているが、コード上でもろくろを回している余裕はあるのだろうか。
新機能を追加する時に困る
- キャラクターが走る機能を追加しよう ← まだなんとかなる
- 走るときスタミナを消費させよう ← スタミナコンポーネントのメソッドを呼び出して共依存に...
- ローリングできるようにしよう ← 無敵時間管理コンポーネントにも依存
「上位階層に移譲すればいいじゃん」と気づいたアナタ、大正解。
でも人間はアホなのでコード書いてるときに気づけないんや(n敗)
脳死で機能追加の場所を特定できる命名は重要。
CharacterMove を「現実見ろよ法(仮)」で解決する
「現実見ろよ法(仮)」を使うとこの問題をスマートに解決できる(できてほしい)。
ここでは「CharacterMove」を「Leg」に置き換えてみる。
リスト等で複数纏める場合
- Legs でいい
- もっとも、脚をいっぱい集めるなんて吉良吉影の脚版みたいなこと誰がするんやって話だが
機能を分割する場合
- Leg (他の機能から入力を受けて足全体を制御する)
- Bone (足の長さを保持して登れる坂や段差を判定する)
- Muscle (移動速度やジャンプ力を制御)
- Foot (接地判定や地面の法線を取得する機能)
なんかきもいな。
たぶん分割しすぎだと思う。
自分なら Foot と Leg に分割するにとどめるかなぁ。
(一応こういう風に分けられるという例)
ただ、Foot 基準で分割しておくと「足のすべての指に指輪を付けられる」という狂気じみた仕様にも簡単に対応できそうなので間違っていないと思う。
機能を追加する場合
Leg は脚なので「脚にその機能をつけていいのか?」を考えるだけでいい。
付けられないなら他のコンポーネントを作って機能の合成は上位階層に移譲する。
- 走る機能を追加しよう ← 足に機能を追加するだけでOK
- 走るときにスタミナを消費させよう ← 移動部分のみ Leg に実装, スタミナ処理等は上位階層に移譲
- ローリングできるようにしよう ← 移動部分のみ Leg に実装, 他は上位階層に移譲
Leg の親が Player なら、Player にスタミナとローリングのコンポーネントをぶら下げて
Player オブジェクト内でローリングの移動/無敵/スタミナ消費の処理をしかるべきコンポーネントにぶん投げると良いと思う。
現実見ろよ!
いい夢見るなよ!