Java最佳实践:静态final映射值

5

我有一个实用类,其中包含一些值的静态常量映射。我需要在另一个类中访问此映射。我应该将映射声明为公共的,还是应该在实用类内编写一个getter,从而使映射成为私有的?

两种方法都可以,但最佳实践是什么呢?

public MyUtilityClass {
  public static final Map<String, Integer> MAX_LENGTHS = ImmutableMap.of(
      "title", 256,
      "text", 512);

}

public MyAnotherClass {

  public void someMethod() {
    //accessing the map directly
    MAX_LENGTHS.get("title")
  }

}

或者

public MyUtilityClass {
  private static final Map<String, Integer> MAX_LENGTHS = ImmutableMap.of(
      "title", 256,
      "text", 512);

  public static final getMaxLengthMap() {return MAX_LENGTHS;}
}

public MyAnotherClass {
  public void someMethod() {
    //accessing the map directly
    getMaxLengthMap().get("title")
  }
}

实际上,这些键是枚举值。 类似于:

private static final Map<String, Integer> MAX_LENGTHS = ImmutableMap.of(
      MyEnumClass.TITLE, 256,
      MyEnumClass.TEXT, 512);

MyUtilityClass 上的“getter”应该返回键的值,而不是类的用户必须知道键是什么或如何存储。 - MadProgrammer
5个回答

5

getter方法不会增加任何东西-我建议你保持其公开状态。

有意义的做法是创建一个可以直接返回值的方法:

public MyUtilityClass {
  private static final Map<String, Integer> MAX_LENGTHS = ImmutableMap.of(
      "title", 256,
      "text", 512);

  public static final getMaxLength(String item) {return MAX_LENGTHS.get(item);}
}

public MyAnotherClass {
  public void someMethod() {
    //accessing the map directly
    getMaxLength("title");
  }
}

这也使得您以后可以轻松修改底层实现。例如,您可以为未在地图中的项目返回默认值等。

@AndrewTobilko 添加另一个方法。这不是乱搞。可以考虑使用枚举(如果必须枚举值)或使用多个辅助类。 - roookeee
1
@roookeee 我认为这样做不太好。你将要编写一堆 Map 的方法,只是为了备份一个私有字段。如果该类还有其他与 Map 无关的字段/方法(对于实用程序类来说这是非常可能的),那该怎么办呢?(我曾经采用过这种方法,现在我觉得它没有任何好处) - Andrew Tobilko
这也使得您以后可以轻松修改底层实现。我想知道它有多重要...它是一个在内部使用的实用类,不会公开暴露,对吧? - Andrew Tobilko
@AndrewTobilko 我不是说应该这样做 - 我只是给 OP 提供另一个选项。根据这个简单的例子,我同意公共字段完全没问题。 - assylias
我总是会选择仅公开所需数据的实现。 我会让辅助函数返回Optional,因为并非每个可能的String都被映射,这已经提供了应用附加回退逻辑而不暴露内部数据结构的方式。 - roookeee
显示剩余3条评论

4
你正在使用 guava 项目中的 ImmutableMap;因此,这是一个真正的不可变 Map。
将它设为 public 不会伤害任何人 - 因为没有人可以以任何方式修改该 Map。

2
我必须说,你最好一开始就使用一个“Enum”。因为这个映射似乎总是完全静态的: "最初的回答"。
public enum MaxLength {
    TITLE(256),
    TEXT(512);

    public final int value;

    MaxLength(int value) {
        this.value= value;
    }
}

不再需要那个实用类,现在你可以直接获取该值:

最初的回答

int length = MaxLength.TITLE.value;

0

这取决于您需要对地图做什么。

直接允许访问地图(将其设置为公共),将使任何人都有可能在没有任何限制的情况下使用和修改该地图。

在您的情况下,地图是最终且不可变的,因此这不适用。

但是,如果您想将访问权限限制为某些内容,例如title,则正确的选择是创建一个仅返回String的方法。

将地图设置为公共,或创建一个返回整个地图的方法没有区别。


地图是不可变的,因此您的第一个观点不适用。 - assylias
@Leviand 修改那个地图时没有任何限制,但不要修改 OP 正在使用的地图。 - Eugene
你是对的,我已经修正了我的回答。 - Leviand

0
我认为在拥有类中添加一个getter方法是可行的方式。
public MyUtilityClass {
  private static final Map<String, Integer> MAX_LENGTHS = ImmutableMap.of(
      "title", 256,
      "text", 512);

  public static int getLength(final String key) {
     return MAX_LENGTHS.get(key);
  }
}

public MyAnotherClass {
  public void someMethod() {

    int x= MyUtilityClass.getLength("title")
  }
}

这样可以使得MyAnotherClass不需要知道getter的任何实现细节,从而使得测试时的模拟更加容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接