2. 命名規則を守る
名前をつけるというのは簡単なようでいて非常に重要かつ難しい行為です。
コンピュータサイエンスには、難しい問題が2つだけある。キャッシュの無効化と、名前付けである
(There are only two hard things in Computer Science: cache invalidation and naming things.)
Phil Karlton
それが何であるか、何をするためのものなのかを少ない文字で伝えなければいけません。それに、あちこちで違うフォーマットで名付けが行われていると可読性が下がり、混乱の元になります。以下にC#の命名規則を記します。
大前提
- 意味や目的が分からない名前をつけない
num: 何の数?count: 何のカウント?temp: 一時的であってもちゃんと名前はつけるoyoo: ふざけないGameManager: ゲームの何をManageするの?
- 略語を使わない
d: day…?n: …?mp: :@MP:…?- (HPやBPMなど略語の方がメジャーな場合はその限りではない)
- (↑HPは略すのちょっと微妙かも)
- (ループや数式の場合は1文字の変数でもよい)
フィールドと変数
- 基本的にcamelCase、定数とプロパティはPascalCase
- 名詞で命名する
- bool型には動詞の接頭辞を付ける
- boolは例えば「プレイヤーは死んでいるか」などの質問や条件にtrueかfalseで答えるものなので、
isDeadのように動詞の接頭辞をつける
- boolは例えば「プレイヤーは死んでいるか」などの質問や条件にtrueかfalseで答えるものなので、
- 宣言は1行につき1つとする
- 冗長な名前を避ける
- 例えば
PlayerクラスにフィールドplayerScoreを作るなら、単にscoreとするべき
- 例えば
- 冗長な初期化子を避ける
- int型の
= 0, 参照型の= nullなど
- int型の
- varの乱用を避ける
- 型が明らかでない場合にvarを使うのはやめよう
- (自由) privateなフィールドの接頭辞に
_をつけない- 個人的にはいらないと思う
- (自由) privateなフィールドにprivate修飾子をつけない
- 修飾子をつけないと自動的にprivateになるので、publicと見分けやすくするためにもつけなくていいんじゃないかという話
- こっちも個人的にいらないと思う
csharp
// ❌ Bad
public class Player : MonoBehaviour
{
public int num; // 何の数?
public float d; // ???
public string temp; // 一時的でも名前はつける
public bool dead; // 動詞の接頭辞がない
public int playerScore; // Playerクラスなのにplayer~は冗長
public int x = 0, y = 0; // 1行に複数宣言 & 冗長な初期化子
int hp = 0; // 冗長な初期化子 & 略語
GameObject obj = null; // 冗長な初期化子 & 意味不明な名前
}
// ✅ Good
public class Player : MonoBehaviour
{
public int RemainingLife { get; private set; } // PascalCase (プロパティ)
public float DashDuration { get; private set; } // 意味が明確
public string CurrentQuestName { get; private set; }
public bool IsDead { get; private set; } // 動詞の接頭辞
public int Score { get; private set; } // Playerクラスなので冗長さを排除
int currentHitPoint; // camelCase
int maxHitPoint;
[SerializeField] GameObject bulletPrefab; // publicにせずSerializeField
}enum
- PascalCase
- 名前には単数形を用いる
- 名前の接尾辞は
TypeやStateなどが考えられる
- 名前の接尾辞は
csharp
// ❌ Bad
public enum enemies // 複数形 & camelCase
{
slime, // camelCase
goblin,
dragon,
}
// ✅ Good
public enum EnemyType // 単数形 & PascalCase & 接尾辞Type
{
Slime, // PascalCase
Goblin,
Dragon,
}
public enum CharacterState // 接尾辞State
{
Idle,
Running,
Jumping,
}クラスと構造体とインターフェース
- PascalCase
- 名詞または名詞句で命名する
- インターフェースには接頭辞として
Iをつける
csharp
// ❌ Bad
public class manage_player { } // snake_case & 動詞
public class data { } // 曖昧
public interface Damageable { } // 接頭辞Iがない
// ✅ Good
public class PlayerController : MonoBehaviour { } // PascalCase & 名詞句
public class EnemySpawner : MonoBehaviour { } // 役割が明確
public struct AttackResult { } // 構造体もPascalCase
public interface IDamageable { } // 接頭辞Iメソッド
- PascalCase
- 動詞または動詞句で命名する
- boolを返すメソッドの名前は質問形式にする
- bool変数と同様
csharp
// ❌ Bad
void Enemy() { } // 名詞 (何をするメソッド?)
void PlayerAttack() { } // 動詞で始まっていない
bool Dead() { return false; } // 質問形式でない
// ✅ Good
void SpawnEnemy() { } // 動詞 + 目的語
void ApplyDamage(int amount) { } // 動詞句
bool IsDead() { return hitPoint <= 0; } // 質問形式
bool HasItem(ItemType type) { } // 質問形式
bool CanAttack() { } // 質問形式Managerクラスはなぜいけないのか
クラス名として GameManager や UIManager など、Manager という名前を付けている例が多く見られます。しかし、この名前は避けるべきです。
なぜなら、Manager という言葉の意味が広すぎて曖昧だからです。例えば GameManager は具体的にゲームの何を管理しているクラスなのかが全く分かりません。単に責務が不明瞭で名付けが下手というのもそうですが、曖昧な名付けをすると「ゲームの処理なんだからとりあえず GameManager に詰め込んでおけばいいや」という風に、あらゆるロジックがどんどん追加されていってしまう危険があります。そうなると一瞬で数百行もある神クラスへと成長してしまいます。
Manager を始めとする曖昧な名前は避け、代わりに具体的な責務を表す名前を付けましょう。(といってもAIくんはお構いなしにManagerクラスを作ってしまうので困ったものです…)