/* 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());
}
答案 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将阻止并发问题。