2016-05-21 7 views
4

私は大規模なリファクタリングプロジェクトの途中です。コードには5000行のメインクラスがあり、すべてのものに注入され、すべてが保存され、すべての共通コードがあります。Javaアプリケーションデータの保存とアクセスに最適なアプローチ

私は分析とデザインの専門家ではありませんが、私は自分の能力を最大限に引き出しています。メインクラスに依存するクラスをリファクタリングして約80%作成されました。

アプリケーションの開始時に初期化され、アプリケーションの使用期間を通じてほとんどすべてによってアクセスされるいくつかのタイプのデータがあります。たとえば、何百ものパラメータを保持するConfigクラスがあります。

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

これにより、コード内のどこからでもClientData.getInstance()。getConfig()。getParam( "param")を呼び出すことができますが、これが最善のアプローチであるとは思われません。

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

私は、上のグーグルでてきたし、オフの週のためにこれを行うには良い方法を見つけるしようとしているが、何とか私は常にデータベース・キャッシングの話スレッドで終わる

+0

方法について['java.util.Properties'](http://www.mkyong.com/java/java-properties-file-examples/)を使用していますか? –

+0

データはプロパティに格納され、起動時に読み込まれますが、いくつかのスレッドがあり、多くの便利なメソッドとクライアントデータを介してアクセスされる約10種類のクラスを解析するための膨大なものがあります。もしそれがまだ良いユースケースだと思うなら、例を挙げて答えてみてください。それを試してみます – SMC

+0

注射フレームワークを使いたいと思うように聞こえます。これらのBeanをアプリケーションクラスに挿入します。これにより、ClientData.getInstance()。getConfig()。getParam( "param")の代わりにプロパティを直接注入することもできます。@Inject @Named( "param")String param;あなたはそのフィールドで利用できるデータを持っています。 – pandaadb

答えて

2

不変(設定)の場合は、「スレッドセーフなアプリケーション全体のデータアクセス」を提供このシンプルなチュートリアルに従うことができます。 Typesafeのconfig(Brian Kentのコメントで示唆されているように)はまさにこれを行います。 これには静的クラスまたはシングルトンは含まれません。静的なクラスとシングルトンは今あなたの目的に役立つかもしれませんが、 ですが、将来的には迷惑をかける可能性があります。彼らは便利だが、その使用を制限しようとする。

設定データを読み込んで解析した後で初期化を行う必要があります。通常、アプリケーションの起動時に、他の処理スレッドが開始される前に実行されます。コンフィグレーションデータが正常でない場合は、高速で失敗してプログラムを終了するために、初期化ではコンフィグレーションデータを可能な限り検証する必要があります。

多くの設定データをバンドルすると、「通信の隠線」を作成できます。例えば。ある値を更新すると、他の値への更新も必要になるため、アプリケーションが失敗します。すべての構成データを1つのファイルに入れてそこからロードするのはまったく問題ありませんが、アプリケーション(何百もの構成オプションを持つ)は、アプリケーションのさまざまな部分で使用されるセットで構成データを分割する必要があります。これにより分離が改善され、単体テストに役立ちます。また、あまりにも多くの厄介な驚きを受けることなく、今後アプリケーションを変更することができます。オブジェクト内から

  1. シングルトンSettings.getInstance().getConfigForThisModule()を呼び出す:

    は、2つの構成データのセットを使用する方法があります。

  2. 構成データをコンストラクタまたはsetConfig(ConfigForThisModule config)経由で使用する各オブジェクトを提供します。

第1のアプローチは、脆弱性の可能性があるSettings.getInstance().getConfigForACompletelyUnrelatedModule()を呼び出さないという規則に依存します。第2のアプローチは、「依存性注入」に沿ったものであり、将来的な証明になる可能性があります。 リファクタリングの際に両方のアプローチを混在させることができます。一貫性があることを確認するだけです(アプリケーションのすべての部分で使用される構成データにシングルトンアプローチを使用するなど)。

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

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

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

0

申し訳ありませんが、質問があり、少しあいまいですあなたはあなたのプログラムの他の部分で使われている設定やキャッシュされたオブジェクトを保存しようとしていますか?あなたは、のparamsの数百を持って管理しやすいブロックに分割アップして設定を開始しますので

1)1持っている論理ブロックにあなたの設定パラメータを分割:単純なプロパティファイルを使用して1つの対応が取るつもり-itsあなたがプログラム

3へのenv変数を介して基地の場所を渡すことを確認して、任意の時点でそれらを変更できるように、これらのプロパティファイルを外部化しなければならないいくつかの時間

2))書きますあなたの設定を保持するためにApache commons configurationをラップするユーティリティクラス(シングルトン)。 (ベース位置から* .propertiesを読み込み、プロパティを1つの設定オブジェクトにマージする)これは、スレッドを開始する前に実行する必要があります。

4)config.getXXXX()メソッドを使用してコード内の構成のparamを参照してください

はApache Commonsの設定も、あなたの特性は、ファイルシステム上の変更を提出するとき設定をリロードする能力を持っています。

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

0

それはあなたが必要なだけの文字列のプロパティ値だ場合、あなたもそのためのクラスを必要としない - グローバルな施設はすでにあなたのために存在する:System.getProperties()

あなたが行う必要があるのは最初の起動時にプロパティ値をロードされます:

System.setProperty("myKey", "myValue"); // see below how load properties from a file 

は次にどこでも、あなたのコードでそれを読む:

String myValue = System.getProperty("myKey"); 

または

String myValue = System.getProperty("myKey", "my desired default"); 

あなたのコンテナは、次のようになり、外部ファイルからプロパティをロードするために、箱から出して財産の読み込みをサポートしていない場合:

:あなたはこのコードを使用することができます

key1=value 
key2=some other value 
etc... 

Files.lines(Paths.get("path/to/file")) 
    .filter(line -> !line.startsWith("#") || !line.contains("=")) // ignore comment/blank 
    .map(line -> line.split("=", 2)) // split into key/value 
    .forEach(split -> System.setProperty(split[0], split[1])); // load as property 
0

Javaプロパティークラスutilを使用することができます。基本的には、HashTable 参照:https://docs.oracle.com/javase/7/docs/api/java/util/Properties.html

あなたは、ファイルfileName.propertiesを作成して、キーと値のペアにデータを保存する、例えば:

username=your name 
port=8080 

、あなたは、プロパティオブジェクトにロードし、次のようなデータを取得する:

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/

関連する問題