不変 (構成) インスタンスは、「スレッドセーフなアプリケーション全体のデータ アクセス」を提供します。Typesafe の構成(Brian Kent のコメントで提案されているように) はまさにそれを行います。これには静的クラスやシングルトンは含まれないことに注意してください。静的クラスとシングルトンは、現在は目的にかなうかもしれませんが、将来的には面倒になる可能性があります。もちろん便利ですが、使用を制限してみてください。
構成データを読み取って解析した後、初期化を行う必要があります。これは通常、他の処理スレッドが開始される前に、アプリケーションの起動時に行われます。初期化では、構成データが適切でない場合にすばやく失敗してプログラムを終了するために、可能な限り構成データを検証する必要があります。
多くの構成データがまとめられていると、「通信の隠れた回線」が作成される可能性があります。たとえば、1 つの値を更新すると、他の値も更新する必要があるため、アプリケーションが失敗します。すべての構成データを 1 つのファイルに入れてそこからロードすることはまったく問題ありませんが、アプリケーション (何百もの構成オプションがある) では、アプリケーションのさまざまな部分で使用されるセットに構成データを分割する必要があります。これにより、分離が改善され、単体テストが容易になり、将来、多くの厄介な驚きを得ることなくアプリケーションを変更できるようになります。
一連の構成データを使用するには、次の 2 つの方法があります。
- オブジェクト内から singleton を呼び出します
Settings.getInstance().getConfigForThisModule()
。
- 構成データを使用する各オブジェクトに、コンストラクターまたは を介して構成データを提供します
setConfig(ConfigForThisModule config)
。
Settings.getInstance().getConfigForACompletelyUnrelatedModule()
最初のアプローチは、弱点になる可能性のある呼び出さない規則に依存しています。2 番目のアプローチは、「依存関係の注入」に沿ったものであり、将来的にはより確実なものになる可能性があります。リファクタリング中に両方のアプローチを混在させることができますが、一貫性があることを確認してください (たとえば、アプリケーションのすべての部分で使用される構成データにはシングルトン アプローチのみを使用します)。
構成データを使用するための設計をさらに改善するには、次の (可能性が高い) 将来の機能要件を念頭に置いてください: 構成ファイルが更新されると、構成データが再ロードされ、アプリケーションで使用されます。ほとんどのロギング フレームワークは、マルチスレッド アプリケーションのパフォーマンスに影響を与えることなく、この機能要件をサポートしています。とりわけ、アプリケーションには次のものが必要です。
- 新しい構成データが適切でない場合、プログラムは終了せず、代わりにエラーがログに記録され、古い構成データが使用されたままになります。初期化手順では、「新規開始時のロード」シナリオと「再ロード」シナリオの両方を処理する必要があります。ここから取り除かなければならない主なことは、初期化手順は再利用可能である必要があり、アプリケーションの他の (実行中の) 部分に影響を与えてはならないということです (再び分離)。
- 寿命の長いオブジェクトは、構成データのローカル コピーまたは のインスタンスへの参照を保持しない場合があります
ConfigForThisModule
。代わりにSettings.getInstance()...
(または更新されたインスタンスを返すことができる他のメソッド) を定期的に呼び出す必要があります。
- 古い構成を新しい構成に置き換えても、エラーが発生しない場合があります。
AtomicReference
技術的には、構成の置き換えは、で返される新しい構成インスタンスでを更新するのと同じくらい簡単Settings.getInstance()...
です。ただし、これは構成データ セットの分離がテストされる場所でもあります。あるモジュールで古いセットを使用し、別のモジュールで新しいセットを同時に使用しても問題はありません。
構成データは、一種の「グローバル状態」と見なすことができます。それを念頭に置いて、何をすべきか、何を避けるべきかについてのさらなる設計上のポイント (この回答に部分的に露骨にコピーされています) について、次の 2 つの質問で説明します。