💬

クソコードに対してどこまで対処するか

2024/01/09に公開

クソコードの特徴

ソフトウェア開発の現場で時折遭遇する「クソコード」という用語は、多くのプログラマーにとって身近なものです。しかし、実際に何がクソコードを構成するのか、その定義はプロジェクトや個々の開発者によって異なります。ここでのクソコードとは以下のような特徴を持つコードを指します:

  • コードにコメントがない: コード内にコメントがないため、複雑なロジックやコードの意図が明確でない。これにより、他の開発者がコードを理解しにくくなり、保守や拡張が困難になる。

  • DB カラムにコメントがない: データベースのカラムに説明を加えるコメントが不足しているため、各カラムの目的やデータの性質が不明確です。例えば、「code」というカラムに単に数値が入っている場合、その数値が何を表すのか判断が難しくなります。

  • コードの意図が不明瞭: コードに書かれている処理が不透明で、その目的や機能が読み取りにくい。これは、命名規則の不適切さやロジックの複雑さ、ドキュメントの欠如などが原因で発生する。

  • 変数名の情報が少ない: 変数名が一般的で抽象的なため、その変数が何を表しているのかが不明確である。例えば、dataitemのような名前は、変数の用途や内容を明確にしない。

  • 変数のスコープが広い: 変数が宣言されてから使用される場所までの範囲が広すぎると、変数の追跡が困難になり、バグの原因となることがある。

  • 処理が長い: 関数やメソッドが過度に長いと、それらを理解、維持、テストすることが困難になる。

  • 各層が結合している: アプリケーションの異なる層が密結合していると、各層を独立してテスト、修正、再利用することが難しくなる。

  • テストがない: 単体テストや統合テストが欠如していると、コードの信頼性を保証するのが難しくなる。

  • ドキュメントがない: コードベースに対するドキュメントが不足していると、新しい開発者が既存のコードを理解しにくくなり、プロジェクトへの参加障壁が高くなる。

  • 使われていない DB カラムがある: データベース内に不要なカラムが存在すると、データの整合性を保つのが難しくなり、データベースのパフォーマンスにも悪影響を与えることがある。

  • コピペのコードが大量にある: 同じまたは似たようなコードが複数箇所で繰り返されていると、コードの保守性が低下し、変更が困難になる。

  • Object 型を多用している: 汎用的なObject型の過度な使用は、型安全性の欠如を招き、ランタイムエラーの可能性を高める。

  • コメントアウトしたコードが大量にある: コメントアウトされたコードが多く残っていると、現在のコードベースに何が有効で何が無効であるかを理解するのが難しくなる。

この記事では、上記のようなクソコードに遭遇した際の対処方法を、具体的なステップとともに紹介します。目的は、効率的かつ実践的な方法でコードベースを改善し、長期的にソフトウェアの品質を高めることです。

さらに、この記事ではクソコードとの共存方法にも焦点を当てます。すべてのクソコードを根絶することは現実的ではなく、また時にはコストがかかりすぎることもあります。したがって、ここではコストの高い改善策を避け、可能な限り効率的にクソコードを改善する方法について議論します。攻め際を見極め、賢くクソコードと共存する方法を学びましょう。

テストの容易さについての考察

テストが容易に書ける状態のコードは、一般的には「クソコード」とは考えられません。良質なコードの特徴の一つに、テストのしやすさがあります。テストが書きやすいことは、そのコードがよく整理され、適切に構造化されていることを意味し、これによりコードの振る舞いが理解しやすくなります。このような特性は、コードの保守性と全体的な品質を向上させる重要な要素です。本記事で紹介されているリファクタリング方法は、テストが困難または不可能なレベルのクソコードを対象としています。

クソコードとの共存

ソフトウェア開発において、クソコードと完全に無縁でいることはほぼ不可能です。プロジェクトの進行、チームの変化、技術の進化など、様々な要因によって、コードベースには常に改善の余地が生じます。重要なのは、すべてのクソコードを排除しようとするのではなく、それらと効率的に共存する方法を見つけることです。

クソコードの存在についての考察

クソコードが多く存在するという事実は、それが一定の利益をもたらしてきた歴史があることを示唆しています。多くの場合、クソコードは短期的な目標達成や迅速な市場への投入のために生まれます。これは、厳しい納期や急な要件変更、リソースの制限など、ビジネス上の圧力の下での開発が原因であることが多いです。

プロジェクトの初期段階では、完璧なコードを書くよりも、機能を迅速に実装し、製品を市場に投入することが優先される場合があります。このような状況下では、コードの品質や将来の保守性よりも、現在のデリバリーの速さや機能の実装が重視されることが一般的です。その結果、技術的負債が蓄積され、長期的にはメンテナンスや拡張が困難なクソコードが生まれます。

しかし、クソコードが生み出される背景には、それによって一時的にでもビジネス目標が達成され、企業に利益がもたらされたという歴史があります。そのため、クソコードをただ単に悪と捉えるのではなく、ビジネスと技術のバランスを取る上での必然的な産物として理解することが重要です。この理解に基づいて、適切なタイミングでのリファクタリングや技術的負債の返済が、健全なソフトウェア開発のサイクルにおいて鍵となります。

すべてのクソコードを排除することの非現実性

クソコードを完全に排除しようとする試みは、しばしば時間とリソースを過剰に消費します。現実的には、妥協が必要です。プロジェクトの優先順位、リソースの可用性、デリバリーの期限など、多くの要因がこの決定に影響を与えます。完璧を目指すよりも、チームや案件の状況など現実的な目標を設定することが大事です。

効率的な共存方法の探求

クソコードとの共存は、優先順位付けと効率的なアプローチの選択によって実現されます。最も重大な問題や、最も影響の大きい改善策に注力し、少ない労力で最大の効果が得られる方法を選びます。

糞コードの改善方法

糞コードの改善方法に対する評価を以下の三つの指標で五段階評価します。

  1. おすすめ度: この改善方法を実施することの一般的な推奨度。
  2. 手間: 改善方法を実施するのに必要な労力や時間。
  3. 効果: 改善方法を実施した結果として期待される効果の大きさ。

各指標は以下のように五段階で評価されます。

  • ⭐: 低い / 少ない / 小さい
  • ⭐⭐: やや低い / やや少ない / やや小さい
  • ⭐⭐⭐: 普通 / 普通 / 普通
  • ⭐⭐⭐⭐: やや高い / やや多い / やや大きい
  • ⭐⭐⭐⭐⭐: 高い / 多い / 大きい

これらの評価基準に基づいて、各改善方法のおすすめ度、手間、効果を評価します。

1. 新しいエンドポイントを追加して機能拡張

  • おすすめ度: ⭐⭐⭐⭐

  • 手間: ⭐⭐

  • 効果: ⭐⭐⭐⭐

  • 既存の API を直接改修するのではなく、新たなエンドポイントを追加することで、機能を拡張します。これにより、既存のシステムやクライアントに影響を与えることなく、新しい機能を導入できます。

  • 新しいエンドポイントの追加は、既存の API の安定性を維持しつつ、必要な機能の拡充を可能にします。これは、特に既存のシステムが広く使用されている場合に、効果的かつリスクの低いアプローチです。

  • この方法は、既存の API のコードベースに大きな変更を加えることなく、新しい要件に対応するための柔軟で安全な解決策を提供します。

2. 適切なコメントの追加

  • おすすめ度: ⭐⭐⭐

  • 手間: ⭐⭐

  • 効果: ⭐⭐⭐

  • コード内の各セクションに、その意図やロジックを説明するコメントを適切に追加する。これにより、コードの可読性と保守性が向上します。

  • 一部の開発者は、過剰なコメントの追加に反対することがありますが、これは一般的には整理されたコードに対しての指摘です。複雑で読みづらいコードの場合、適切なコメントは理解を助け、誤解を防ぐ手助けとなります。

  • 特にコードの品質が低い箇所には、他の開発者に注意を喚起する意味でコメントを付けることが有効です。これは、特に経験の浅い開発者に対して、誤ったコーディングスタイルの採用を防ぐためにも重要です。

3. 長大な関数の分割

  • おすすめ度: ⭐⭐⭐⭐⭐

  • 手間: ⭐⭐⭐

  • 効果: ⭐⭐⭐⭐⭐

  • 一つの長い関数や複雑なロジックを、より小さく、管理しやすい複数の関数に分割することで、コードの可読性と再利用性を向上させます。

  • 関数の分割は、コードの理解を容易にし、テストやデバッグの効率を高めます。また、変更や拡張が必要な場合にも、対応がしやすくなります。

  • しばしば、関数を分割することは初期にリスクを伴うかもしれませんが、長期的な視点で見ると、コードベースの品質を大幅に向上させることができます。特にテストの作成や保守性の観点から、関数の適切な分割は重要です。

4. Object 型をクラスにマッピングする

  • おすすめ度: ⭐⭐⭐

  • 手間: ⭐⭐⭐⭐

  • 効果: ⭐⭐⭐⭐

  • 汎用的な Object 型の使用を避け、より具体的なクラスにマッピングすることで、コードの型安全性と保守性を向上させます。

  • このアプローチには時間がかかる場合がありますが、特に頻繁に使用される処理に対して実施することで、最大の効果が得られます。

  • この変更は呼び出し元のコードにも影響を与えるため、慎重な実装が必要です。しかし、長期的にはコードの品質とメンテナンス性が大幅に向上します。

5. IDE による変数名のリファクタリング

  • おすすめ度: ⭐⭐⭐⭐⭐

  • 手間: ⭐⭐

  • 効果: ⭐⭐⭐⭐

  • 統合開発環境(IDE)のリファクタリング機能を利用して変数名をより適切かつ明確にします。これにより、コードの可読性が大幅に向上します。

  • 一貫した命名規則を採用することで、コードの理解が容易になり、将来的な保守作業も効率化されます。

  • 適切に命名された変数は、コードの読みやすさを向上させ、他の開発者が理解しやすくなります。これは特にチームでの開発において非常に重要です。

  • 類似する変数名が多用されている場合は、「3. 長大な関数の分割」のアプローチも検討してみてください。

6. 不要なコメントアウトの削除

  • おすすめ度: ⭐⭐⭐⭐⭐
  • 手間: ⭐
  • 効果: ⭐⭐⭐
  • コード内に存在する不要なコメントアウトされた部分は、迅速に削除することが推奨されます。これにより、コードの行数が減り、スクロールの必要性が減少します。
  • コメントアウトされたコードの削除は、コードベースをクリーンで整理された状態に保つのに役立ちます。これにより、読みやすさが向上し、他の開発者がコードを理解する際の混乱を避けることができます。

7. DB のカラムには積極的にコメントを付けよう

  • おすすめ度: ⭐⭐⭐⭐⭐
  • 手間: ⭐⭐
  • 効果: ⭐⭐⭐⭐
  • データベースのカラムにコメントを付けることで、各カラムの目的や役割が明確になります。これはデータベースの構造を理解しやすくし、新しい開発者が迅速にプロジェクトに参加できるようにするのに役立ちます。
  • コメントの量が増えても、データベースのカラムはソースコードと異なり、その量が問題になることはほとんどありません。データベースの透明性を高めるために、この点はさほど気にする必要がありません。
  • データベースは通常、ソースコードより長期間使用されることが多いです。そのため、長期的な視点でカラムに対して有用なコメントを付けることは、データベースの維持と運用において非常に効果的です。

まとめ

この記事では、ソフトウェア開発における「クソコード」という一般的な問題に焦点を当て、その特徴とそれに対する改善策について詳しく解説しました。私たちの最終目標は、コードの品質を長期的に向上させることにあります。クソコードを一度にすべて排除することは非現実的であるため、より実用的なアプローチとして、手間と効果を考慮したコストパフォーマンスの高い効率的な方法を選ぶことが推奨されます。このような戦略により、ソフトウェアの品質を持続的に改善し、より良い開発環境を築くことができます。効果を実感したいときは、一番手間が少ない修正から始めることをおすすめします。

Discussion