保守性
コードは書かれるよりもはるかに頻繁に読まれます。保守性こそが、3年経ったコードベースを喜びにするか、タールピットにするかを分けるものです。次の開発者(それは6か月後のあなたかもしれません)のために最適化しましょう。
ルール
- 一つの機能は一箇所に。 機能ごとにパッケージ化します(backend/core/SKILL.mdを参照)。単一の変更は隣接するファイルに影響し、レイヤー全体に散らばらないようにします。
- インターフェースはモジュール境界でのみ。 機能内部では具象クラスで十分です。インターフェースは、呼び出し元が境界を越えて契約に依存できるように存在するものであり、すべてのクラスを装飾するためのものではありません。
- 削除する、コメントアウトしない。 デッドコードや
// TODOが永遠に残るコメントは腐ります。Gitが覚えています。IDEは覚えておく必要はありません。 - 小さな純粋関数を優先する。 テストが容易で、推論しやすく、合成しやすい。副作用はシステムの端に置き、中に散らばらないようにします。
- テストは動作をカバーし、実装をカバーしない。 内部を書き換えてもテストが壊れてはいけません。壊れるなら、テストは間違ったものに結合しています。
- 公開APIはバージョン管理する。 破壊的変更は新しいバージョンまたは機能フラグの背後で行います。決して無言のリネームはしません。
- 静的シングルトンよりも依存性注入。 静的要素はテスト不可能で結合を隠します。依存関係を渡し、テストではモックにします。
- 依存関係を固定し、定期的に更新する。 ロックファイルをコミットし、Renovate/Dependabotで自動PRを設定します。2年遅れると、予定外の2週間の移行作業が発生します。
- 「何を」ではなく「なぜ」を文書化する。 コードは何を示します。コメントはビジネスルール、歴史的な制約、明白でないトレードオフを説明します。
- CIでリント、フォーマット、型チェックを実施する。 アドバイスではなく、ブロッキングにします。人間は設計について議論すべきであり、スペーシングについて議論すべきではありません。
- ビルドをグリーンかつ高速に保つ。 不安定または遅いテストは無視され、無視されれば何も保護しません。
危険信号
- 約500行を超えるファイル、または約10個以上のパブリックメソッドを持つクラス — 通常は、機能が出ようとしているサインです。
- 孤児になったヘルパーが死にに行く共有「utils」パッケージ。
- テストをパスさせるためにテスト対象をモックする。
- 「そのモジュールには触らないで。もう誰も理解していない。」
- CIのビルド時間が数十分単位で測定される。