こんにちは、デザイニウムのGeraldです。 今日はクリーンコードを紹介して、色々なアドバイスを示します。 コーディング例では、Unity / C#で作成されたコードを使用していますが、クリーンコード原則は他のプログラミング言語に適用されます。
目次
- 「クリーンコード」って何?
- なぜクリーンコードが必要か?
- 意味のある名前
- 意図による名前
- 読みやすい名前
- クラス名
- メソッド名
- コンスタント
- 単一の責任
- リファクタリング
すべて表示
「クリーンコード」って何?
「Clean Codeはシンプルで直接的なもの。
Clean Codeは散文のようなコードだ」 --Grady Booch
私の経験とクリーンコードを読んだ結果に基づいて、クリーンなコードは:
* 読みやすい
同僚は説明なしでコードをわかります
* 簡単
各クラスとメソッドには1つの責任があります
* 上品
コードをざっと見るだけで、コードを理解できます
* フォーマットうまくされている
奇妙な改行なし、正しい括弧など
独自の投稿に値するので、自動テスト(単体テスト、統合テスト、受け入れテスト)については書きません。
なぜクリーンコードが必要か?
クリーンコードを作成するのは品質測定だから時間が掛かります。 価値がある理由は次のとおりです:
* チームは作者なしで働くことができます
経験豊富なプログラマーは確かにコードに遭遇しましたが、彼らは理解できず、作者の助けを必要としました
* クリーンなコードは拡張が簡単です
理解しやすいコードは、面倒なコードよりも拡張して再利用する方が安全です。
* 簡単なバグ修正
特に「単一の責任原則」を維持する場合(詳細は後で説明します)、バグの理由をすばやく特定できます
* 簡単なパフォーマンスの向上
動作を壊さずに簡単なコードを操作する方が安全です
* 数年後のコードを理解
コードは遅かれ早かれ忘れられます
では、どのようにクリーンコードしますか?
意味のある名前
Yコードを作成するときは、常に名前が必要です。 クラス、メソッド、変数 、ファイル、ディレクトリ。 多くのプログラマーはネーミングの力を過小評価しています。
良い名前はコード内で多くのことを説明するため、コードがクリーンになります。
意図による名前
意図的に変数に名前を付けることにより、変数はその機能と使用方法を明らかにします。 クラスでこのような変数を簡単にたどることができます。
rb = GetComponent<Rigidbody>(); // bad
d = Vector3.Distance(pointA, pointB);
rigidbody = GetComponent<Rigidbody>(); // good
distance = Vector3.Distance(pointA, pointB);
読みやすい名前
プログラミング言語はコミュニケーションについて理解する必要があります。 実生活では、誰も略語で話すことはありません。
変数characterControllerを読み取るだけで、それが何を実行するかが既にわかっているため、宣言にジャンプする必要はありません。
cc = GetComponent<CharacterController>(); // bad
characterController = GetComponent<CharacterController>(); // good
クラス名
クラス名は、たとえばPlayer、Enemy、PlayerInventoryなどの名詞でなければなりません。
Manager、Info、Dataなどの一般的な名前は、単一責任の原則に違反し、すべてのコードを1つの単一クラスに配置するため、避けてください。
メソッド名
メソッド名は常にPlay、StopAudio、MovePositionのような動詞または動詞句である必要があります。
コンスタント
数値と文字列にコンスタントを使用して、意図を示します。
velocity.y -= 9.81f * Time.deltaTime; // bad
ShowMessage(“Player left the match”);
velocity.y -= Gravity * Time.deltaTime; // good
ShowMessage(PlayerLeftText);
単一の責任
メソッドとクラスが行うことは1つだけです。 より多くのメソッドは、簡潔さを向上させる小さなメソッドを意味します。
また、メソッドとクラスを増やすことで、コードに意図的な名前を付け、コマンドの巨大なブロックを置き換えます。
void Update() // bad
{
moveDirection = new Vector3(horizontalAxis, 0.0f, verticalAxis);
characterController.Move(moveDirection * Time.deltaTime);
if (Input.GetButtonDown("Fire1")) {
Instantiate(ShootParticle);
}
}
このメソッドを最初に見るとき、これが実際に何をするかを考える必要があります。 メソッド内のコードを抽出することにより、理解しやすく、読みやすくなります。
Update()メソッドは2つのことを行うので、いくつかのメソッドを作成しましょう。
void Update() { // good
MoveCharacter();
Shoot();
}
private void MoveCharacter() {
moveDirection = new Vector3(horizontal, 0.0f, verticalAxis);
characterController.Move(moveDirection * Time.deltaTime);
}
private void Shoot() {
if (Input.GetButtonDown("Fire1")) {
Instantiate(ShootParticle);
}
}
ほとんどのIDEでは、コードを選択し、「抽出メソッド」のショートカットを使用して簡単にリファクタリングできます。
リファクタリング
高品質のコードの場合、コードを確認して最適化することが重要です。 最初は完璧なコードを書くことはできませんが、後で改善することはできます。
特に、試行錯誤する必要がある場合は、不正なコードを記述してもかまいません。 しかし、後でそれをリファクタリングしてください!
void Update() { // bad
if (Input.GetKeyDown(KeyCode.F9)) {
ScreenCapture.CaptureScreenshot(Application.dataPath +
"/screenshot.png", 4);
}
}
これは問題なく機能しますが、シンプルさ、読みやすさ、拡張性を向上させることができます:
private const KeyCode ScreenShotKey = KeyCode.F9;
private const int QualityMultiplier = 4;
private const string FileName = "screenshot.png";
void Update() { // good
if (Input.GetKeyDown(ScreenShotKey)) {
TakeScreenshot();
}
}
private void TakeScreenshot() {
ScreenCapture.CaptureScreenshot(GetScreenshotPath(),
QualityMultiplier);
}
private string GetScreenshotPath() {
return Application.dataPath + "/" + FileName;
}
コメント使わないで
「不正なコードはコメントしないで。書き直して。」
Brian W. Kernighan and PJ Plaugher
コメントでコードを説明しないでください。 コメントは通常一度書かれますが、正しく維持されません。 作成されたコードの約50%は、書き換え、最適化、リファクタリング、変更、またはバグ修正されています。 しかし、誰もコメントを修正しません。
コメントを書く代わりに、時間をかけてコードを改善してください。
コードを説明する必要があると思われる場合は、コードをメソッドまたは変数に抽出します。
void Update() { // bad
speedometer.Show(currentSpeed * 3.6f)); // convert to km/h
}
void Update() { // good
speedometer.Show(ConvertToKilometerPerHour(currentSpeed));
}
private float ConvertToKilometerPerHour(float meterPerSecond) {
return meterPerSecond * 3.6f;
}
APIを作成するとき、または回避策を実行するときのみ、コメントを使用できます。
概要
* メソッド、変数、クラスに適切な名前を使用して
* コードは本のように読まれるべきです
* メソッドには1つのタスクしかありません
* クラスの責任は1つだけです
* 機能するときにコードを最適化して
* コメントを使用しない
編集後記
Geraldさんは、会津オフィス所属のエンジニアです✨今回はWebエンジニアに加えてゲームプログラマーの経験もある彼に自由に書いてもらいました。いくつかテーマの候補があった中でも特に「クリーンコード」は社内エンジニアからのリクエストが多数(笑)この日本語版のほかに、英語版も書いてもらいました❗しかも母国語はドイツ語なハズ…。す、凄すぎるー❗そしてありがたい✨というわけで、今後もGeraldさんの投稿をお楽しみに😊