簡體   English   中英

私有靜態變量是必需的公共setter嗎?

[英]Is a public setter necessary for private static variable?

/* Atleast is it needed in this case?*/
 public class Service
{       
         private static List<String> subscribedFields;
    private static List<String> unsubscribedFields;
         //---------------------------------  
         // is this necessary?
         //---------------------------------
    public static void setFields(List<String> subscribedFields, List<String> unsubscribedFields)
    {
        Service.subscribedFields = subscribedFields;
        Service.unsubscribedFields = unsubscribedFields;
    }
    public static List<String> getSubscribedFields()
    {
        return subscribedFields;
    }
    public static List<String> getUnsubscribedFields()
    {
        return unsubscribedFields;
    }
}
// some other class
public class User{
     // Is this not enough to change the lists? Isn't the setter redundant? 
     Change(Service.getSubscribedFields());
     Change(Service.getUnsubscribedFields());

}

不,私有變量並不總是需要公共setter。 提供公共setter(以及getter)的想法是基於 - 類等外部實體需要訪問您正在編寫的特定代碼段的內部。 Getter和setter為此提供了公共接口。 但是,您不一定需要為您創建的每個私有變量提供公共getter或setter,因為該私有變量可能僅存在於該類的內部私有用途。

您必須根據代碼的特定需求決定是否特別需要訪問您的私有變量。

根據評論中的ada問題進行更新

您可以直接授予用戶訪問列表的權限(是的 - 他們可以使用getter然后編輯列表)。 如果您信任代碼的用戶,這可能會有效。 但是,由於各種原因,您可能不希望讓他們直接訪問您的列表(特別是因為它讓他們自由地執行他們想要做的事情,如果您在應用程序中有線程,它可能會產生問題等) 。 在這種情況下,您應該在基礎列表中提供接口。 例如,在您的類中,您可能希望提供以下方法,而不是提供getSubscribedFields()。

// Pseudocode
public String getSubscribedField(int i) {
  return subscribedFields.Get(i);
}

public String addSubscribedField(String field) {
  subscribedFields.Add(field);
}

希望這有助於為您澄清一些事情。

在這種情況下,更流行的選擇是使用一個用字段初始化一次的Singleton。 然而,即便是Singleton也不是一個好主意,但要做到這一點,就要求我們更多地了解你要做的事情。 在大多數情況下,您可以使用靜態實例,使其成為具有較長生命周期的類的成員。 例如,如果這些字段與數據庫字段相關,則將其與表類關聯,該表類保存有關數據庫表的信息。

真的,這取決於你想要完成的事情。

不,你不應該。 甚至更多你應該避免靜態。

你的班級似乎很容易出現線程安全問題。 我還質疑你將List作為靜態變量的相關性。

另一件事,你的setter不符合JavaBeans setter和getters標准,如果你想與一些常見的框架集成,你可能會遇到問題。

我建議你改變你的班級。 我重構它是為了保持類的責任是持有訂閱。

如果你使用像Spring或Guice這樣的依賴注入框架,你可以簡單地創建一個像這樣的類,並將它注入需要這個對象的類。

    public class SubscriptionServiceUsingDependencyInjection {

    private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();

    public boolean isSubscribed(String field_) {
        return subscribedFields.contains(field_);
    }
    public void subscribe(String field_) {
        subscribedFields.add(field_);
    }
}

否則,如果你真的需要一個Singleton,你可以使用枚舉來實現相同的目標:

    public enum SubscriptionServiceUsingASingleton {
    INSTANCE;
    private final Set<String> subscribedFields = new CopyOnWriteArraySet<String>();

    public boolean isSubscribed(String field) {
        return subscribedFields.contains(field);
    }
    public void subscribe(String field) {
        subscribedFields.add(field);
    }
}

如果在多線程環境中運行此操作,CopyOnWriteArraySet將阻止並發問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM