【问题标题】:Better way to keep String type values globally?在全局范围内保持 String 类型值的更好方法?
【发布时间】:2014-03-06 02:17:58
【问题描述】:

我希望一些 String 值对我来说是可用/可访问的,以通过 Java 处理应用程序。不同的班级将需要它们。我想知道在整个应用程序中保留和访问这些值的最佳方式。

  1. 我知道的一种方法是在 Java 中使用 Enum 模式。我可以将一个字符串值与每个枚举相关联,然后访问它。就像这里给出的一样。 Best way to create enum of strings?

  2. 二是维护一类带String值的常量。

什么是最好的方法,以便遵循良好的设计并干净地访问所有内容。

我想知道。

public class StringValues
{
   public static final String ONE = "one";
   public static final String TWO = "two";
}

我正在添加更多细节。

我将使用这些短名称字符串创建数据库查询。因此,在实例化数据库时我将在一个地方使用所有字符串并创建查询

但是在创建查询之后,我需要一个特定类的字符串池的片段/部分,以便我可以为选定的类注册侦听器,而不是为池中的所有字符串。每个类都应该知道,它只需要 1-2 个字符串名称来注册运行时侦听器,而不是所有的字符串名称。

我一次需要所有字符串(在应用程序开始期间)然后我只需要 2 或 3 个或更多但不是全部。

这是让您了解我的确切设计问题的代码。

/**
*This class will be used to create Views in Database.
*/
class Views
{
    public static final String BY_NAME = "byName";
    public static final String BY_DATE = "byDate";
    public static final String BY_GENDER = "byGender";

    //For every String I am going to create Views in Couchbase.
}

/**
*This class knows to which Views it needs to listen to. If any change in its views occurs then
* it will take action. In case of byDate change it is intended to take an action.
*/
public class NewestMember
{
    String[] viewsToQueryFor = {"byDate"};

    //This class will call only these views and will register for them.
}


public class Male
{
    String[] viewsToQueryFor = {"byName", "byGender"};

    //This class will call only these views and will register for them.
}


public class Female
{
    String[] viewsToQueryFor = {"byName", "byGender"};

    //This class will call only these views and will register for them.
}

我不想这样做。为此,我需要在其他类中保留 String 值的额外开销。

【问题讨论】:

  • Id 取决于这些值是真的恒定还是可配置的。如果是第二种,最好将它们保存在 *.properties 文件中。
  • 通常会将常量放在实际需要它们的类中。避免使用Constant interface antipattern
  • @Hoosier 如果有那么多常量,那么您可能有一些设计问题 - 考虑将常量分组到描述其用途的 enum 实例中,例如public enum CompassPointpublic enum Gender 等。使用enum 的一个优点是不能将Gender.MALE 传递给需要CompassPoint 的方法,因此该方法不需要检查无效输入。您还可以通过enum 挂起更多数据。
  • 从更新到问题,这似乎是一个经典的 XY 问题。根本不应该有常数。查询应该在 DAO 层中定义并在那里使用。它们应该通过字符串连接构建,而是通过准备好的语句构建。
  • 既然您提供了代码,如果我理解正确,我会说我坚持我最初的答案。视图名称适用于特定类型的数据。所以这些常量大概应该在PersonView中,而PersonView大概应该是一个枚举。在包含汽车或约会或其他任何东西的集合上应用byGender 视图是没有意义的。对于汽车,您将拥有一个包含 BY_COLOR 和 BY_MODEL 的 CarView 类或枚举。

标签: java design-patterns enums constants


【解决方案1】:

第二个很好。但我不会创建一个类来包含所有不相关的常量。这不成比例,也不自然。相反,在它们所属的类中定义常量。例如:

public class Victim {
    public static class DEFAULT_MALE_NAME = "John Doe";
    public static class DEFAULT_FEMALE_NAME = "Jane Doe";
    ...
}

public class CreditCard {
    public static final String DEFAULT_TYPE = "Visa";
    ...
}

编辑:

现在您提供了一些代码,看来您实际上应该定义一个或多个枚举,每个枚举都封装了应用于给定集合的视图的概念。

【讨论】:

  • 但是根据我的要求,我需要保留一个包含所有常量的池。我将从该池中创建查询,然后对于任何要求,一个类将拥有这些池字符串的一小部分来调用它们以用于自己的目的。
  • 如果您不告诉我们这些常量是什么以及您想要它们做什么,我们将无法理解您的意思。想象一下,如果 JDK 的所有常量都定义在一个类中:它将有数千个不相关的常量,并且具有使它们唯一的巨大名称,这将是一团糟。没有理由将不相关的常量放在一个类中。也许您的常量密切相关,那么将它们放在一个类中就可以了。
  • 我将更新问题的信息。请稍等。我需要你的帮助。
  • 我已经更新了我的问题。它将帮助您了解我实际面临的问题。
  • 我还是不太明白。也许一个代码示例会有所帮助。但我同意鲍里斯的评论:这似乎是一个 XY 问题,你可能根本不应该有常量。
【解决方案2】:

我会将常量分组并使用第二个建议,其中类的名称应该是特定于域的东西,而不仅仅是“常量”。考虑一个数据库字段名称池,其中每个类都可以表示一个表。我只会使用这种模式,如果

  1. 我需要很多这样的值,所以我更喜欢一些分组。
  2. 我的应用程序的多个部分都使用了这些值,我不想重复它们以避免出现错误。

否则,这些值应在 using 类中定义为 private 常量字段。

此外,我将创建此类final 并添加private 构造函数,该构造函数会抛出AssertionError(否则此类常量holer 类仍然可以反射性地创建)。这让每个用户都清楚,这些类不应该被用于其他东西,而不是它们的常量。我会进一步避免接口,因为它们倾向于被实现以允许某种static import,即使这些常量类并不真正代表实际的域类型。这会给您的应用程序增加一些不必要的冗长。

请注意,Strings(和原语)是编译时常量,将由编译器内联。这意味着这些常量持有者类永远不会在运行时加载,并且在使用它们时绝对没有性能或内存损失。就像您将String 复制粘贴到它使用的每个位置一样。因此,良好的分组是最高优先级。这种内联不适用于“字符串枚举”,这就是我不鼓励使用它们的原因。如果您的常量类型变得比Strings 更复杂,我会再次考虑enums,因为它们可以表示接口类型并提供定义此类常量的简洁方式。

【讨论】:

    【解决方案3】:

    由于以后不能扩展枚举,最好的方法是使用常量,即public static final

    【讨论】:

      猜你喜欢
      • 2022-01-27
      • 2012-02-05
      • 2013-06-30
      • 1970-01-01
      • 2019-01-25
      • 1970-01-01
      • 2020-05-03
      • 2012-03-08
      • 2020-12-17
      相关资源
      最近更新 更多