4

私は大規模なリファクタリング プロジェクトの真っ最中です。コードには 5000 行のメイン クラスがあり、すべてに注入され、すべてが格納され、すべての共通コードが含まれていました。

私は分析と設計の専門家ではありませんが、できる限り物事を分離しており、メイン クラスに依存するクラスをリファクタリングして、作成した新しいクラスを使用することで約 80% を達成しています。

アプリケーションの起動時に初期化され、アプリケーションの存続期間中、ほぼすべてのデータからアクセスされるタイプのデータがあります。たとえば、何百ものパラメーターを保持する Config クラスがあります。

私が採用したアプローチは、いくつかのシングルトンを作成することです。最も中心的なものは、GUIData と ClientData の 2 つです。GUIData にはアプリケーションのメインフレームへの参照が含まれ、clientdata には config および他の同様のクラスへの参照が保持されます。

これにより、コードのどこからでも ClientData.getInstance().getConfig().getParam("param") を呼び出すことができますが、これが最善の方法だとは思いません。

クラスのインスタンスを含むこれらのデータシングルトンの代わりに、個々の静的クラスを検討しましたが、一部のクラスにはコンストラクターが必要です。

これを行うためのより良い方法を見つけるために、1週間グーグルでオンとオフを繰り返してきましたが、どういうわけか、データベースキャッシングについて話しているスレッドにいつも行き着きます

4

4 に答える 4

3

不変 (構成) インスタンスは、「スレッドセーフなアプリケーション全体のデータ アクセス」を提供します。Typesafe の構成(Brian Kent のコメントで提案されているように) はまさにそれを行います。これには静的クラスやシングルトンは含まれないことに注意してください。静的クラスとシングルトンは、現在は目的にかなうかもしれませんが、将来的には面倒になる可能性があります。もちろん便利ですが、使用を制限してみてください。

構成データを読み取って解析した後、初期化を行う必要があります。これは通常、他の処理スレッドが開始される前に、アプリケーションの起動時に行われます。初期化では、構成データが適切でない場合にすばやく失敗してプログラムを終了するために、可能な限り構成データを検証する必要があります。

多くの構成データがまとめられていると、「通信の隠れた回線」が作成される可能性があります。たとえば、1 つの値を更新すると、他の値も更新する必要があるため、アプリケーションが失敗します。すべての構成データを 1 つのファイルに入れてそこからロードすることはまったく問題ありませんが、アプリケーション (何百もの構成オプションがある) では、アプリケーションのさまざまな部分で使用されるセットに構成データを分割する必要があります。これにより、分離が改善され、単体テストが容易になり、将来、多くの厄介な驚きを得ることなくアプリケーションを変更できるようになります。

一連の構成データを使用するには、次の 2 つの方法があります。

  1. オブジェクト内から singleton を呼び出しますSettings.getInstance().getConfigForThisModule()
  2. 構成データを使用する各オブジェクトに、コンストラクターまたは を介し​​て構成データを提供しますsetConfig(ConfigForThisModule config)

Settings.getInstance().getConfigForACompletelyUnrelatedModule()最初のアプローチは、弱点になる可能性のある呼び出さない規則に依存しています。2 番目のアプローチは、「依存関係の注入」に沿ったものであり、将来的にはより確実なものになる可能性があります。リファクタリング中に両方のアプローチを混在させることができますが、一貫性があることを確認してください (たとえば、アプリケーションのすべての部分で使用される構成データにはシングルトン アプローチのみを使用します)。

構成データを使用するための設計をさらに改善するには、次の (可能性が高い) 将来の機能要件を念頭に置いてください: 構成ファイルが更新されると、構成データが再ロードされ、アプリケーションで使用されます。ほとんどのロギング フレームワークは、マルチスレッド アプリケーションのパフォーマンスに影響を与えることなく、この機能要件をサポートしています。とりわけ、アプリケーションには次のものが必要です。

  • 新しい構成データが適切でない場合、プログラムは終了せず、代わりにエラーがログに記録され、古い構成データが使用されたままになります。初期化手順では、「新規開始時のロード」シナリオと「再ロード」シナリオの両方を処理する必要があります。ここから取り除かなければならない主なことは、初期化手順は再利用可能である必要があり、アプリケーションの他の (実行中の) 部分に影響を与えてはならないということです (再び分離)。
  • 寿命の長いオブジェクトは、構成データのローカル コピーまたは のインスタンスへの参照を保持しない場合がありますConfigForThisModule。代わりにSettings.getInstance()...(または更新されたインスタンスを返すことができる他のメソッド) を定期的に呼び出す必要があります。
  • 古い構成を新しい構成に置き換えても、エラーが発生しない場合があります。AtomicReference技術的には、構成の置き換えは、で返される新しい構成インスタンスでを更新するのと同じくらい簡単Settings.getInstance()...です。ただし、これは構成データ セットの分離がテストされる場所でもあります。あるモジュールで古いセットを使用し、別のモジュールで新しいセットを同時に使用しても問題はありません。

構成データは、一種の「グローバル状態」と見なすことができます。それを念頭に置いて、何をすべきか、何を避けるべきかについてのさらなる設計上のポイント (この回答に部分的に露骨にコピーされています) について、次の 2 つの質問で説明します。

于 2016-05-25T23:51:02.750 に答える
0

Java Properties クラス util を使用できます。基本的には HashTable リファレンスです: https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html

ファイル fileName.properties を作成し、データをキーと値のペアで保存します。次に例を示します。

username=your name
port=8080

次に、それを Properties オブジェクトにロードして、次のようなデータを取得します。

Properties prop = new Properties();
load the file...
String userName = prop.getProperty("username")
String port = prop.getProperty("port")// you can parse it to int if needed

私が提案するのは、次のような構成の種類ごとにプロパティ ファイルを作成することです。

  1. clientData.properties
  2. appConfig.properties

この簡単なチュートリアルに従うことができます http://www.mkyong.com/java/java-properties-file-examples/

于 2016-05-25T08:09:10.217 に答える
0

申し訳ありませんが、質問は少しあいまいです。プログラムの他の部分で使用される構成またはキャッシュされたオブジェクトを保存しようとしていますか?

何百ものパラメーターがあるため、構成を管理可能なブロックに分割することから始めます

1) 構成パラメータを、単純なプロパティ ファイルと 1:1 で対応する論理ブロックに分割します。これには時間がかかります。

2) これらのプロパティ ファイルは、いつでも変更できるように外部化する必要があります。環境変数を介してベースの場所をプログラムに渡すようにしてください。

3) Apache Commons 構成をラップして構成を保持するユーティリティ クラス (シングルトン) を作成します。(ベースの場所から *.properties を読み取り、プロパティを 1 つの構成オブジェクトにマージします) これは、スレッドが開始される前に実行する必要があります。

4) config.getXXXX() メソッドを使用して、コード内の構成パラメーターを参照します。

Apache Commons 構成には、ファイルシステムでプロパティ ファイルが変更されたときに構成をリロードする機能もあります。

これが完了したら、Spring や Guice などの DI コンテナーを使用して、構成されたオブジェクトをキャッシュします。

于 2016-05-24T17:52:52.380 に答える