gpt4 book ai didi

java - 实现常量对象的最佳方法是什么?

转载 作者:行者123 更新时间:2023-11-30 00:41:45 24 4
gpt4 key购买 nike

首先,我可能应该说“常量对象”这个词可能不太正确,可能已经意味着与我所想的完全不同的东西,但这是我能想到的最好的术语来描述我的东西我在谈论。

所以基本上我正在设计一个应用程序,我遇到了一些似乎存在现有设计模式的东西,但我不知道它是什么或要搜索什么,所以我将描述它是什么是我正在努力做的,我正在寻找关于最佳实现方式的建议。

假设你有一个类:

public class MyClass {
private String name;
private String description;
private int value;

public MyClass(String name, String description, int value) {
this.name = name;
this.description = description;
this.value = value;
}

// And I guess some getters and setters here.
}

现在假设你事先知道这个类只会有 3 个实例,并且数据也是预先知道的(或者至少会在运行时从文件中读取,确切的文件名是提前知道)。基本上我得到的是数据不会在运行时更改(一旦设置)。

起初我认为我应该在某处声明一些静态常量,例如

public static final String INSTANCE_1_DATA_FILE = "path/to/instance1/file";
public static final String INSTANCE_2_DATA_FILE = "path/to/instance2/file";
public static final String INSTANCE_3_DATA_FILE = "path/to/instance3/file";
public static final MyClass INSTANCE_1 = new MyClass(getNameFromFile(INSTANCE_1_DATA_FILE), getDescriptionFromFile(INSTANCE_1_DATA_FILE), getValueFromFile(INSTANCE_1_DATA_FILE));
public static final MyClass INSTANCE_2 = new MyClass(getNameFromFile(INSTANCE_2_DATA_FILE), getDescriptionFromFile(INSTANCE_2_DATA_FILE), getValueFromFile(INSTANCE_2_DATA_FILE));
public static final MyClass INSTANCE_3 = new MyClass(getNameFromFile(INSTANCE_3_DATA_FILE), getDescriptionFromFile(INSTANCE_3_DATA_FILE), getValueFromFile(INSTANCE_3_DATA_FILE));

现在很明显,无论何时我想使用 3 个实例中的一个,我都可以直接引用常量。

但我开始考虑可能有一种更简洁的方法来处理这个问题,接下来我想到的是做类似的事情:

public MyClassInstance1 extends MyClass {
private static final String FILE_NAME = "path/to/instance1/file";

public String getName() {
if (name == null) {
name = getNameFromFile(FILE_NAME);
}
return name;
}

// etc.

现在每当我想使用 MyClass 的实例时,我可以只使用我想要的实例,例如

private MyClass myInstance = new MyClassInstance2();

或者可能更好的方法是让它们成为单例并执行以下操作:

private MyClass myInstance = MyClassInstance3.getInstance();

但我不禁认为这也不是处理这种情况的正确方法。我是不是想多了这个问题?我是否应该在某处使用 switch 语句,例如

public class MyClass {
public enum Instance { ONE, TWO, THREE }

public static String getName(Instance instance) {
switch(instance) {
case ONE:
return getNameFromFile(INSTANCE_1_DATA_FILE);
break;
case TWO:
etc.
}
}
}

谁能告诉我实现它的最佳方法?请注意,我用 Java 编写了示例代码,因为这是我最擅长的语言,但我可能会用 C++ 实现应用程序,所以目前我更想寻找与语言无关的设计模式(或者只是为了有人告诉我使用我已经提到的简单解决方案之一)。

最佳答案

如果您希望这些值是常量,那么您将不需要 setter ,否则代码可以简单地更改常量中的值,使它们不是很常量。在 C++ 中,您可以只声明实例 const,尽管我仍然会去掉 setter,因为有人总是可以丢弃 const。

该模式看起来不错,尽管每次请求时您都在创建一个新实例,这对于常量来说并不常见。

在 java 中,您可以创建“智能”枚举,例如

public enum MyClass {
ONE(INSTANCE_1_DATA_FILE),
TWO(INSTANCE_2_DATA_FILE),
//etc...

private MyClass(String dataFile)
{
this(getNameFromDataFile(dataFile), other values...)
}

private MyClass(String name, String data, etc...)
{
this.name = name;
// etc..
}

public String getName()
{
return name;
}
}

在 C++ 中,您将创建 MyClass,使用私有(private)构造函数获取文件名和任何其他需要初始化的内容,并在 MyClass 中为每个实例创建 static const 成员,并为其赋值使用私有(private)构造函数创建的 MyClass 的新实例。

编辑:但现在我看到了这种情况,我认为使用静态值并不是一个好主意。如果 ActivityLevel 的类型是您的应用程序的基础,那么您可以将不同类型的 Activity 级别枚举为常量,例如java 或字符串枚举,但它们只是占位符。实际的 ActivityDescription 实例应该来自数据访问层或某种提供者。

例如

enum ActivityLevel { LOW, MED, HIGH  }

class ActivityDescription
{
String name;
String otherDetails;
String description; // etc..
// perhaps also
// ActivityLevel activityLevel;

// constructor and getters
// this is an immutable value object
}

interface ActivityDescriptionProvider
{
ActivityDescription getDescription(ActivityLevel activityLevel);
}

如果需要,您可以使用静态方法或 ActivityDescription 实例的枚举来实现提供程序,或者更好的是 ActivityLevel 到 ActivityDescription 的映射,您可以从文件加载,从 spring 配置中获取等。要点是使用一个获取给定 ActivityLevel 的实际描述的接口(interface)将您的应用程序代码与系统中如何生成这些描述的机制分离。它还可以在测试 UI 时模拟接口(interface)的实现。您可以使用固定静态数据集无法实现的方式通过模拟实现对 UI 施加压力。

关于java - 实现常量对象的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2970455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com