私有静态变量是必需的公共setter吗?

时间:2011-02-03 14:59:13

标签: java

/* 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());

}

4 个答案:

答案 0 :(得分:6)

不,私有变量并不总是需要公共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);
}

希望这有助于为您澄清一些事情。

答案 1 :(得分:1)

在这种情况下,更受欢迎的选择是使用您使用字段初始化一次的Singleton。然而,即便是Singleton也不是一个好主意,但要做到这一点,就要求我们更多地了解你要做的事情。在大多数情况下,您可以使用静态实例,使其成为具有较长生命周期的类的成员。例如,如果这些字段与数据库字段相关,则将其与表类关联,该表类保存有关数据库表的信息。

真的,这取决于你想要完成的任务。

答案 2 :(得分:1)

不,你不应该。甚至更多你应该避免静态。

答案 3 :(得分:1)

您的课程似乎非常容易出现线程安全问题。我还质疑你将List作为静态变量的相关性。

另一件事,你的setter与JavaBeans setter&amp;如果你想与一些常见的框架集成,那么你可能会遇到问题。

我建议你改变班级。我重构它是为了保持类的责任是持有订阅。

如果你使用像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将阻止并发问题。