レガシーコードからの脱出: 大規模 Salesforce リファクタリングで安定運用と高速修正を両立する

7 min read
SalesforceApexLegacy CodeRefactoringQuery Delegation PatternApexEloquentMission CriticalRevenue SystemsTDDObject Oriented Design
Query Delegation Pattern と ApexEloquent で、ミッションクリティカルな請求書システムを「壊れそうなレガシーコード」から「安定して保守しやすいアーキテクチャ」へと変えた実例。

🏢 プロジェクトの背景: 売上計上に直結する請求情報生成の厳しい品質要件

私が担当していた Salesforce プロジェクトで、 売上計上に直結する 請求情報を自動生成するプログラム に対して、 大規模な仕様追加が行われることになりました。 この請求情報は会社の売上数値としてそのまま使われるため、 生成ロジックには 間違いが一切許されない 、 という極めて厳しい条件がついていました。

しかし既存のコードベースは完全に手続き型で書かれており、 現行仕様をカバーするテストクラスが実質的に存在していませんでした。 機能を追加すれば、 ほぼ確実にバグを呼び込むことは火を見るより明らか。リリース後の安定運用に強い不安が残る、 高リスクな状態でした。

⚠️ 課題: レガシーコードとテスト不足がビジネスリスクを押し上げる

特に深刻だったのは次の点です。

🔗 手続き型コードに絡まる密結合

ビジネスロジックとデータアクセスロジックが密に結合しており、 ある箇所の修正が思わぬ場所に影響する危うさを抱えていました。 売上数値に直結する請求情報でこれが起きれば、 業務へのインパクト計り知れません。

📊 テストカバレッジの不足

既存機能の品質を担保するテストが足りておらず、 大規模な仕様追加を入れる際に デグレを防ぐ手段がない 状態でした。 売上に関わるデータで、 手動テストには限界があり、 潜在的なバグが本番に混ざり込む危険性がありました。

⏱️ DML とトリガーのオーバーヘッド

特に数年運用されたこのプロジェクトでは様々なオブジェクトに複雑なトリガーが張り巡らされており、テストデータの作成だけでかなりの時間を要しているためTDD のような開発スタイルは現実的でなくなり、 結果的にテスト不足が固定化されていました。

💡 解決策: オブジェクト指向設計への移行と ApexEloquent の導入

これらの課題に対して、 既存コードを 思い切ってオブジェクト指向設計にリファクタリング するアプローチを提案し、 実行しました。 自前で開発していた Query Delegation Pattern と ApexEloquent を導入することで、 根本的な解決を目指しました。

具体的には以下を進めました。

🎯 責務の明確な分離

ビジネスロジックとクエリの目的をドメイン層に閉じ、 純粋なデータ I/O の責務は Repository 層 (ApexEloquent) に切り離しました。 これにより、 売上計上ロジックの複雑性を適切にカプセル化でき、 変更容易性が大幅に向上しました。

🧪 モック可能なテスト基盤

ApexEloquent のモック Repository 機能を活用することで、 実 DB に依存せず、 高速かつ安定して回るテスト環境を構築しました。 これによって、 トリガーや自動化ツールの影響を受けずにコアロジックを 徹底的に単体テスト できる状態を作りました。 「間違いが許されない」 請求情報生成ロジックを、 何度でも網羅的に検証できるようになったのは大きな転換点です。

🔄 段階的なリファクタリングとテストの追加

既存コードのリファクタリングと並行して、 修正・追加する機能から優先的に ApexEloquent ベースのテストクラスを整備していきました。

🎉 結果: 売上データの品質確保と、 高速な修正の両立

この戦略は、 はっきりとした成果に繋がりました。

✅ 高品質なリリースと安定運用

大規模な仕様追加にもかかわらず、 リリース後のシステムは極めて安定して動作し、 当初懸念していた重大バグの発生を防ぐことができました。 売上データの正確性が担保され、 ビジネスへのマイナスインパクトを回避できました。

⚡ デグレなしの高速修正

リリース数か月後、 当初は想定していなかった 5 年契約の特殊ケース でバグが発生しました。 しかし、 Query Delegation Pattern と ApexEloquent によって積み上がっていた高品質なテスト群のおかげで、 この複雑な不具合を、 デグレを起こさずに 素早く確実に修正 できました。 安定運用を維持したまま、 売上に直結する重大バグの影響を最小限に抑えられました。

🎭 まとめ: ミッションクリティカルなシステムにおけるアーキテクチャの力

このプロジェクトは、 売上データのようなミッションクリティカルなシステムを扱うとき、 土台となるアーキテクチャの品質がそのままビジネス成果に直結する ことを示してくれました。 Query Delegation Pattern と ApexEloquent は、 目の前の技術課題を解いただけでなく、 長期的な保守性と、 ビジネス要請への素早い対応力 の基礎を作ってくれました。

責務の明確な分離・網羅的なテスト・モック可能なアーキテクチャ。 これらの組み合わせは、 厳しい要件を持つ業務システムを扱いながら、 変化に対応する俊敏さも維持するために、 やはり欠かせない構成要素だと改めて実感しています。