2017-09-19 5 views
0

次のコードでは、PropertyValueが構築されている間に、2つの静的セットが設定されます。この方法は理にかなっていますか?コンストラクタに静的変数を持たせることは意味がありますか?

class PropertyValue{ 

    String cid; 
    String property; 
    String value; 

    public static Set<String> properties = new HashSet<>(); 
    public static Set<String> values = new HashSet<>(); 

    public PropertyValue(String cid, String property, String value) { 
     this.cid = cid; 
     this.property = property; 
     this.value = value; 

     properties.add(property); 
     values.add(value); 
    } 
} 
+4

にPropertyValueをの設定を保存しない場合は、文字列のあなたの二組を保つことができます。しかし、別々に、任意の種類の可変静的変数を持つことは、通常、反パターンです。 –

+0

これらの値に関心を持つクライアントコードがあれば、索引付けを処理できるようにする方がはるかに優れています。 – chrylis

+0

静的カウンタのようには機能しませんか? – marlon

答えて

1

メンバ変数を静的にする必要があるのは、メンバの寿命をオブジェクトの寿命に拘束したくない場合だけです。おそらく、作成または破棄されたオブジェクト間で共有されるカウンタがあります。または、オブジェクトがインスタンス化または作成される前に保持する必要がある関数があります。たぶん、子クラスによって共有される静的メンバーを持つ基本クラスがあります。それらは私が一般的にメンバを静的にする唯一の時間です。

あなたの例では、クラスがどのように実装されているかの完全な範囲を知らなくても、それが意味を成しているかどうかを判断することは本当に難しいため、伝えるのは難しいです。

別に静的セットのは良いアイデアであるかどうかから
1

...

コードは、静的初期化子に配置する必要があります。これにより、クラスがロードされたときに静的コンテンツが確実に準備されます。クラスの設計によっては、コンストラクタが決して呼び出されない可能性があります。

static { 
    // do the work 
} 
+1

*コードは静的なイニシャライザに配置する必要があります。*いいえ 'public static Set properties = new HashSet <>();'は 'static {}'ブロック内にある必要はありません。静的初期化は 'static {}'ブロックと同じです。 –

1

は限りデザインが行くように...

公共フィールドは、この場合に設定のが、一般的に悪い考えです。他のクラスがSetにアクセスする必要がある場合は、静的メソッドを使用してください。

スタティックセットとマップは、クラスのすべてのインスタンスで設定情報が使用されている場合に意味があります。ただし、通常、インスタンスはコンテンツを変更できないようにしてください。私の前の答えで述べたように、静的なイニシャライザを使用してセットまたはマップをロードする必要があります。

2

これはキーバリューペアのキャッシュ設計のようですが、スレッドセーフではありません。

なぜマップの代わりに2つのセットがありますか?

あなたはhttps://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom

import java.util.Hashtable; 
import java.util.Map; 

public class Properties 
{ 
    private Map<String,String> properties = new Hashtable<>(); 

    private Properties(){} 

    private static class PropertiesHolder{ 
     private final static Properties instance = new Properties(); 
    } 

    public static Properties getInstance(){ 
     return PropertiesHolder.instance; 
    } 

    public void put(String property, String value){ 
     properties.put(property, value); 
    } 

    public void get(String property){ 
     properties.get(property); 
    } 
} 

シングルトンホルダー付きスレッドセーフシングルトンとHashtableの

を作ることができるし、自分のクラスに

Properties properties = Properties.getInstance(); 
    properties.put("foo","bar"); 
    properties.get("foo"); 

を使用する

class PropertyValue{ 

    String cid; 
    String property; 
    String value; 

    public PropertyValue(String cid, String property, String value) { 
     this.cid = cid; 
     this.property = property; 
     this.value = value; 

     Properties properties = Properties.getInstance(); 
     properties.put(property, value); 
    } 
} 

しかし、私は、このキー値 "store"を維持するPropertyValueクラスの責任ではないと思います。 このストアは、新しいPropertyValueインスタンスの後(または前)にコンストラクタではなく読み込まれます。

https://en.wikipedia.org/wiki/Single_responsibility_principle

[いいえ、そうでないペアによってプロパティと値を格納する必要があり、または直接シングルトン

+0

これは、ポストされたコードの動作を完全に変更します。独立した独立した2つの値のセットは、おそらく単に遭遇するすべての別々の値のセットを保持することになります。あなたが掲示したように 'Map <> 'を使うと、コードの意味全体が、2つの値を互いに意味をなさない方法でマッピングすることを単に追跡するのを変えるだけです。あなたは、それがOPが必要とするものであると仮定しています。 *静的なフィールドはスレッド*によってユニークなものは何ですか?あなたの実装はスレッドセーフでもなく、同じ* HashMap <>の同時変更です。 –

+0

それは良いアイデアではないかもしれないが、私はそれが安全だと思う(http://www.wikipedia.org/wiki/Initialization-on-demand_holder_idiom)と思う。 2つのセットを保存するためにこのコードを適合させることは難しくありません –

+0

あなたはHashMapが同期化されていないので、スレッドセーフではありませんでした。それはsyncronizedされているHashtableの使用によって修正されています –

関連する問題