開発の手法 development-practices
完了の定義に従って作業 work-according-to-a-definition-of-done
各チームは、何を意味するかについて異なる定義を持っていますが、受け入れる前に、ストーリーが定義された条件を満たすようにすることが重要です。
チームでよく指定される条件には、次のものがあります。
- コードの書式設定を確認しました
- コメント/Javadoc が追加されました
- 必要なテスト対象レベルを満たす
- 単体テストと統合テストに合格
- QA 環境で検証済み
- ローカリゼーションの実装
明確に定義された DoD がなければ、多くのことが途中で完了し、何も真の完全なものがない状況に簡単に終わることができます。
コーディングおよびフォーマット規則を定義し、準拠する define-and-adhere-to-coding-and-formatting-conventions
インデントレベルや空白など、重要とは思われないようなものでも、正しいフォーマットでコーディングすることは、読みやすさと保守性に大きな効果があります。チームで表記規則について話し合って合意し、その規則に準拠してコーディングする必要があります。
広範なテスト範囲を目指す aim-for-high-test-coverage
プロジェクトの実装サイズが大きくなると、テストに必要な時間が長くなります。テスト範囲が適切に設定されていないと、テスト担当チームの規模を調整できず、結局は開発者がバグに埋もれてしまうことになります。
開発者は TDD を実践し、失敗する単体テストを記述してから、要件を満たす実稼動コードを記述します。QA では、上位レベルから見てシステムが想定どおりに機能することを確認するために、一連の自動受け入れテストを作成します。
Jackalope や Prosper などのカスタムフレームワークを使用して、JCR API のモッキングをより簡単にし、単体テストを記述しながら開発者の生産性を確保できます。
デモの準備を維持 stay-demo-ready
各反復の終了時には、システムのデモを使用できるようにする必要があります。システムのデモを使用可能な状態にしておくことによって、チームは常に実稼動の準備ができているという状態を繰り返すことになり、技術的な負債を維持可能なレベルに保つことができます。
継続的な統合環境を導入して使用する implement-a-continuous-integration-environment-and-use-it
継続的な統合環境を導入すると、単体テストおよび統合テストを簡単かつ反復して実行できます。また、デプロイメントが開発チームから分離されるので、チーム内の他の部門が効率的に作業できるようになり、デプロイメントの安定性と予測可能性が向上します。
ビルド時間を短く抑えて開発サイクルの高速性を維持する keep-the-development-cycle-fast-by-keeping-build-times-low
単体テストの実行に長時間かかる場合、開発者は単体テストの実行を避けるようになり、単体テストの価値が失われます。コードのビルドおよびデプロイに長時間かかる場合は、ビルドおよびデプロイの頻度が減ります。短いビルド時間の方を優先すると、テスト範囲および CI インフラストラクチャにこれまで費やしてきた時間はそのままチームの生産性向上につながります。
Sonar とその他の静的コード分析ツールを微調整し、ツールが出力したレポートに基づいて対処する fine-tune-sonar-and-other-static-code-analysis-tools-and-act-on-their-reports
コード分析ツールは、そのレポートが開発チームメンバー側の対処につながって初めて有用であると言えます。ツールが提供する分析を微調整しないと、ツールが生成する推奨事項は関連性のないものになり、ツールの価値が失われます。
ボーイスカウトのルールを守る follow-the-boy-scout-rule
ボーイスカウトには、「帰るときには、その場所を来たときよりもきれいにする」というルールがあります。開発チームのメンバー全員がこのルールを守り、散らかっていたらそのままにしないで片付けるようにすると、コードは継続的に改善されます。
YAGNI 機能を導入しない avoid-implementing-yagni-features
YAGNI(You Aren't Gonna Need It の略)機能は、今は必要なくても将来は必要になると思われる場合に導入するものです。理想は、今すぐ機能する最も単純なものを導入し、継続的にリファクタリングをおこなって、システムのアーキテクチャが要件に応じて長期間で進化していくようにすることです。このようにすると、重要なことに集中することができ、コードの膨張や機能クリープを防ぐことができます。