コーディング規約をチームで共有しておこう!
目次
- 1 はじめに
- 2 コーディング規約とは
- 3 有名なコーディング規約一覧
- 3.1 クラス・変数・メソッド等の名前は英語で意味が伝わるようにする
- 3.2 クラス・メソッド・プロパティ・public変数・ファイル名・GameObject名・enumの型/定数はPascalCaseで命名
- 3.3 private変数・メソッドの引数・ローカル変数はcamelCaseで命名、さらにprivate変数は頭に_(アンダーバー)をつける
- 3.4 定数はCONSTANT_CASEで命名
- 3.5 抽象クラスはAbstract〇〇と命名
- 3.6 インターフェースはI〇〇と命名、末尾は~able等になりがち
- 3.7 bool型の変数はis〇〇やcan〇〇等と命名
- 3.8 配列は〇〇Array、リストは〇〇Listと命名
- 3.9 Summaryをちゃんと書く
- 4 おわりに
はじめに
こんにちは!RiG++副団体長、コーディング課2回生のにしちゃんです!
本日のアドカレでは、“コーディング規約”と呼ばれる慣習について話していきたいと思います!
また、この記事はUnity×C#での開発におけるコーディング規約についての紹介をします。
プログラミング言語によって採用されがちな規約が多少異なるものもありますので、ぜひ自分のお気に入り言語のコーディング規約を調べてみてください!
コーディング規約とは
皆さんにはコーディングを行うときの自分ルール的なものは何かありますか?
例えば「getterはget〇〇()、setterはset〇〇()という名前にする」だとか、「大域変数はコンストラクタより上にすべて書く」だとかですね。人によっていろいろあると思います。
ではチーム開発になるとどうなるでしょう?
メンバーそれぞれが各々の自分ルールに従ってコーディングしても良いものでしょうか?
もちろんコードの意図が伝われば問題はありませんが、如何せん統一感のない見づらいコードになりがちです。
そこでチーム開発においては、チーム発足時にコーディング規約を定めておくことをおすすめします!
有名なコーディング規約一覧
様々な種類・目的のコーディング規約が制定されていますが、この記事では特に
命名規則
に着目して紹介していきたいと思います。
クラス・変数・メソッド等の名前は英語で意味が伝わるようにする
これは大前提ですね。特に変数についてはついテキトーになりがちです。
タイピングが面倒臭いからとか、一瞬しか使わないからといった理由でテキトーな名前を付けないでください。
//NG:何を保持しているか分からない
int a;
int num001;
//OK:名前が役割を表している
int playerScore;
float currentTime;
なお、真に一時的なデータの保持・退避にしか使用しない場合のtmp・tempであったり、for文で利用するイテレータの i や j 等は例外です。(むしろ逆にその名前が一瞬しか使わないこと・イテレータであることを示している)
クラス・メソッド・プロパティ・public変数・ファイル名・GameObject名・enumの型/定数はPascalCaseで命名
PascalCase(パスカルケース)とは、以下の例に挙げるような、各要素語の頭文字を大文字にし、それ以外を小文字にした命名記法です。
//NG:すべて小文字、または不適切な要素がPascalCaseで命名されている
public int currentplayerhitpoint; //見づらい
private int CurrentTime; //private変数はcamelCaseが適切(後述)
//OK:適切な要素がPascalCaseで命名できている
//クラス名
public class PlayerScore{
//public変数
public int ScoreValue;
//メソッド
public void LogScore(){
~省略~
}
}
基本的に、PascalCaseで命名されたものは外部から参照可能なものになります。
このコーディング規約がチーム内で共有されており、かつ正しくコーディングされていれば、他の人が作ったものでもPascalCaseで命名された要素は参照しても問題ないと考えることができます。
private変数・メソッドの引数・ローカル変数はcamelCaseで命名、さらにprivate変数は頭に_(アンダーバー)をつける
camelCase(キャメルケース)とは、以下の例に挙げるような、先頭の要素語以外の各要素語の頭文字を大文字にし、それ以外を小文字にした命名記法です。
またprivate変数(privateインスタンスも含む)についてのみ、camelCaseで命名した上で先頭に_(アンダーバー)を付けます。
//NG:不適切な命名
private int PlayerHitPoint; //PascalCaseになっている
private int playerAttackPoint; //_をつけ忘れている
//OK:適切な要素がcamelCaseで命名できている
public class Player{
//private変数
private int _hitPoint; //変数
private Vector3 _deltaMove; //インスタンス
//メソッドの引数、ローカル変数
public void CalculateDamege(int damageValue){
~省略~
int correctDamageValue = ~~~;
~省略~
}
}
camelCaseはPascalCaseのときの逆版のような感じです。
基本的に、camelCaseで命名されたものは外部からはアクセスできない保護レベルのものになります。
このコーディング規約がチーム内で共有されており、かつ正しくコーディングされていれば、他の人が作ったものでもcamelCaseで命名された要素は参照できないと考えることができます。
またprivate変数に関しては特別に_(アンダーバー)をつけることを規則としていますので、特に参照してはいけないと考えられます。
定数はCONSTANT_CASEで命名
CONSTANT_CASE(コンスタントケース)とは、以下の例に挙げるような、全てを大文字で記述し各要素語の間に_(アンダーバー)を入れる命名記法です。
//OK
const int MIN_HP = 0;
const int MAX_HP = 999;
これにより、CONSTANT_CASEで命名された要素は不変で変更ができないと考えることができます。
抽象クラスはAbstract〇〇と命名
抽象クラスについては、名前を見ただけでそれが抽象クラスであると分かるように、先頭にAbstractと書いておきます。クラス名なので、もちろんPascalCaseでの命名になります。
//OK
public abstract class AbstractEnemy{
~省略~
}
これにより、名前を見ればこのクラスは直接インスタンス化できないと考えることができます。
インターフェースはI〇〇と命名、末尾は~able等になりがち
インターフェースについては、名前を見ただけでそれがインターフェースであると分かるように、先頭にIをつけておきます。こちらももちろんPascalCaseでの命名になります。
//OK
public interface IClickable{
~省略~
}
public interface IInputSystem{
~省略~
}
これにより、インターフェースでインスタンスを取得する際、インターフェースで取得していることが自然と明示されます。
また余談ですが、インターフェース名の末尾は~ableや~System等になることが多いです。
これはインターフェースの使い方を理解していると自然と納得いくと思いますが、命名に迷ったら参考にしてみてください。
bool型の変数はis〇〇やcan〇〇等と命名
bool型はtrueかfalseしか保持し得ない変数の型です。実際の場面では、YesかNoの情報等を保持させるために使います。
それにあたって、何についてのYes/Noの情報なのかをはっきりと統一的な書式で扱うようにします。
//is〇〇:〇〇かどうか?
private bool _isRunning;
public bool IsClicked;
//can〇〇:〇〇できるかどうか?
private bool _canMove;
public bool CanSelect;
//その他
bool wasBroken;
これにより、この変数がbool型であることが分かりやすくなった他、何についてのYes/Noなのかも理解しやすくなりました。
配列は〇〇Array、リストは〇〇Listと命名
これはあまり有名ではないですが個人的に気に入っているのでさらっと紹介程度に・・・
配列とリストは末尾をArray、Listとすることで自身の構造を明示させます。
よく配列でもリストでも 〇〇s という命名をしがちですが、二者では構造も操作も異なるので、どちらも 〇〇s になるのを避ける意味でも、Array、Listと明示するのは良い規約だと思っています。
Summaryをちゃんと書く
最後に命名規約以外も一つだけ紹介します。
特にメソッドについての話ですが、Summary(要約)をちゃんと書いておきましょう。
コメントでも良いですが、ちゃんとSummaryを書く癖をつけるという意味でも、規約として定めておくのが良いと思います。
/// <summary>
/// ダメージ計算を行うメソッド
/// </summary>
/// <param name = "attackPower">攻撃する側の攻撃力</param>
/// <param name = "defensePower">攻撃される側の防御力</param>
/// <returns>計算後の最終的なダメージ値</returns>
public int CalculateDamageValue(int attackPower, int defensePower){
int damageValue = 計算式;
return damageValue;
}
例えばメソッドのSummaryには、メソッドの簡単な説明・各引数の説明・返り値の説明を記述します。
ちゃんとSummaryを書いておくと、他の人や未来の自分がコードを見たときに意図が伝わりやすいだけでなく、テキストエディタによってはそのメソッドを使おうとするとSummaryを表示してくれるものもあり、実質的な簡易版ドキュメントになります。
おわりに
一般的にUnity×C#での開発で採用されやすいコーディング規約について紹介しました。
あまりぎちぎちにルールで縛っても苦しいので今回は命名規則に焦点を当てて紹介しましたが、チームで共有するきちんとしたコーディング規約を作ってからチーム開発を進めていくと、プロジェクト全体として統一感があり見やすいコードになります。
また個人開発であろうと「数か月後の自分は他人」と誰かが言うほどには、コードの可読性は大切な要素です。
コーディング規約の有無や内容でプログラムの動作に変化はありませんが、常に見やすいコードを書くことを意識していきましょう!
以上です!