1
/
5

クリーンコード

こんにちは、デザイニウムのGeraldです。 今日はクリーンコードを紹介して、色々なアドバイスを示します。 コーディング例では、Unity / C#で作成されたコードを使用していますが、クリーンコード原則は他のプログラミング言語に適用されます。

目次

  1. 「クリーンコード」って何?
  2. なぜクリーンコードが必要か?
  3. 意味のある名前
  4. 意図による名前
  5. 読みやすい名前
  6. クラス名
  7. メソッド名
  8. コンスタント
  9. 単一の責任
  10. リファクタリング

すべて表示

「クリーンコード」って何?

「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さんの投稿をお楽しみに😊

株式会社デザイニウム's job postings

Weekly ranking

Show other rankings
Invitation from 株式会社デザイニウム
If this story triggered your interest, have a chat with the team?