Dav*_*ton 1 c++ java design-patterns coding-style
首先,我应该说"恒定对象"一词可能不太正确,可能已经意味着与我的想法完全不同,但这是我能想到的最好的术语来描述我所说的内容.
所以基本上我正在设计一个应用程序,我遇到的东西似乎可能有一个现有的设计模式,但我不知道它是什么或搜索什么,所以我将描述它是什么我是试图做,我正在寻找有关实施它的最佳方法的建议.
让我们说你有一节课:
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.
}
Run Code Online (Sandbox Code Playgroud)
现在让我们说你事先知道只会说这个类的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));
Run Code Online (Sandbox Code Playgroud)
显然,现在,只要我想使用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.
Run Code Online (Sandbox Code Playgroud)
}
现在,只要我想使用MyClass的实例,我就可以使用我想要的那个
private MyClass myInstance = new MyClassInstance2();
Run Code Online (Sandbox Code Playgroud)
或者甚至更好的做法是让他们成为单身人士而且只做:
private MyClass myInstance = MyClassInstance3.getInstance();
Run Code Online (Sandbox Code Playgroud)
但我不禁想到这也不是处理这种情况的正确方法.我是否在思考这个问题?我应该在某个地方有一个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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉我实现这个的最佳方法?请注意,我已经用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;
}
}
Run Code Online (Sandbox Code Playgroud)
在C++中,您将使用私有构造函数创建MyClass,该构造函数接受初始化所需的文件名和其他任何内容,并static const在MyClass中为每个实例创建成员,并使用私有构造函数为值创建新的MyClass实例.
编辑:但现在我看到的情况我不认为这是一个好主意有静态值.如果ActivityLevel的类型是应用程序的基础,那么您可以将不同类型的活动级别枚举为常量,例如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);
}
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以使用静态实现提供程序,或者使用ActivityDescription实例的枚举,或者更好的是从文件加载的ActivityLevel到ActivityDescription的Map,从spring配置中获取等等.主要的一点是使用接口来获取给定ActivityLevel的实际描述将应用程序代码与系统中如何生成这些描述的机制分离.它还可以在测试UI时模拟界面的实现.您可以使用模拟实现来强调UI,这是使用固定静态数据集无法实现的.
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |