2017-09-19 59 views
0

在以下代碼中,在構造PropertyValue時,會填充兩個靜態集。這種方式有道理嗎?在構造函數中使用靜態變量有意義嗎?

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

不,它不。但是分開來說,任何類型的可變靜態變量通常都是反模式。 –

+0

更好地讓任何客戶端代碼感興趣的這些值處理索引。 – chrylis

+0

這不工作像一個靜態櫃檯? – marlon

回答

1

你應該做一個成員變量靜態的唯一情況是,如果你不想成員的生命綁在對象的生命做。也許你有一個在創建或銷燬的對象之間共享的計數器。或者,也許你有一個函數需要在對象實例化或創建之前持久化。也許你有一個由子類共享的靜態成員的基類。那些是我通常只讓會員變成靜態的時候。

在你的例子中很難說,因爲不知道類是如何實現的全部範圍,所以很難判斷它是否有意義。

1

除了靜態設置的是否是一個好主意......

的代碼應放置在一個靜態初始化。這可確保在加載類時靜態內容已準備就緒。根據類的設計,有可能構造函數永遠不會被調用。

static { 
    // do the work 
} 
+1

*代碼應該放置在一個靜態初始化器中。*編號'public static Set properties = new HashSet <>();'不需要在'static {}塊中。靜態初始化與'static {}'塊完全相同。 –

1

至於設計去... ...

公共領域,在這種情況下設置的,通常是一個壞主意。如果其他類需要訪問Set,他們應該通過靜態方法來完成。

Static Set和Map在所有類的實例都使用配置信息的情況下有意義。但是,通常不應允許實例修改內容。正如我在前面的回答中指出的,應該使用靜態初始化程序來加載Set或Map。

2

它似乎是一種關鍵值對緩存設計,但非線程安全。

爲什麼兩組代替一個Map?

你可以做一個單身持有人線程單和一個Hashtable

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); 
    } 
} 

,並使用

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); 
    } 
} 

但我認爲這不是PropertyValue類的維護此關鍵值「store」的響應性。 此存儲應該在新的PropertyValue實例之後(或之前)填充,但不在構造函數中填充。

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

你可以把你的兩組字符串,如果你不需要通過對的屬性和數據存儲,或者直接存儲一組的的PropertyValue在單

+0

這完全改變了發佈代碼的行爲 - 兩個值的單獨和獨立集合,大概是簡單地保持一組遇到的每個單獨的值。 (這是我的一個假設)使用您所發佈的Map <>'改變了代碼的全部含義,從僅僅追蹤遇到的情況到以無意義的方式將兩個值映射在一起。你認爲這是OP所需要的。 *一個靜態字段是由線程唯一的*是什麼意思?你的實現也不是線程安全的 - 它是* same * HashMap <>的併發修改。 –

+0

好的,這是真的,我改變了很多的代碼來幫助,也許這不是一個好主意,但我認爲它是線程安全的(參見我的鏈接:https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom),它是不難適應這個代碼來保存這兩個集合 –

+0

你對它不是線程安全的,因爲HashMap沒有同步,我的不好。它通過使用同步的Hashtable來糾正 –

相關問題