我使用枚举来定义可以添加到产品中的多个变体(自定义徽标,颜色等).每个变体都有几个选项(ID,两种语言的描述,在此过程中进行更改,价格等).它具有进一步定义变体的方法(例如应使用哪种颜色)或覆盖某些选项.一个产品可以具有存储在ArrayList中的零个,一个或多个变体.此外,某种变化可以不止一次地应用于一种产品.
只要我只使用一个变体,一切都很好.但是,如果我不止一次使用它,似乎所有人都有相同的选择.
示例代码:
TestClass.java:
import java.util.ArrayList;
public class TestClass {
public static void main(String[] args) {
ArrayList<TestEnum> enums = new ArrayList<>();
TestEnum enumVar;
enumVar = TestEnum.TEST1;
enums.add(enumVar);
enumVar = null;
enumVar = TestEnum.TEST2;
enums.add(enumVar);
enumVar = null;
enumVar = TestEnum.TEST2;
enumVar.setOp1("new op21");
enumVar.setOp2("new op22");
enumVar.setOp3("new op23");
enums.add(enumVar);
enumVar = null;
enums.forEach((element) -> {
System.out.println("op1: " + element.getOp1() + "; op2: " + element.getOp2() + "; op3: " + element.getOp3());
/*
Expecting:
op1: op11; op2: op12; op3: op13
op1: op21; op2: op22; op3: op23
op1: new op21; op2: new op22; op3: new op23
Output:
op1: op11; op2: op12; op3: op13
op1: new op21; op2: new op22; op3: new op23
op1: new op21; op2: new op22; op3: new op23
*/
});
}
}
Run Code Online (Sandbox Code Playgroud)
TestEnum.java:
public enum TestEnum {
TEST1("op11", "op12", "op13"),
TEST2("op21", "op22", "op23"),
TEST3("op31", "op32", "op33"),
TEST4("op41", "op42", "op43"),
TEST5("op51", "op52", "op53");
private String op1;
private String op2;
private String op3;
TestEnum(String op1, String op2, String op3) {
this.op1 = op1;
this.op2 = op2;
this.op3 = op3;
}
public void setOp1(String op1) {
this.op1 = op1;
}
public String getOp1() {
return this.op1;
}
public void setOp2(String op2) {
this.op2 = op2;
}
public String getOp2() {
return this.op2;
}
public void setOp3(String op3) {
this.op3 = op3;
}
public String getOp3() {
return this.op3;
}
}
Run Code Online (Sandbox Code Playgroud)
有可能用枚举做我心中的想法吗?
如果是的话,我做错了什么?也许有可能在某个状态下创建一个枚举的副本?
不,你不能用枚举做到这一点.每个枚举值总是只有一个实例.如果您更改枚举上的数据(例如,使用您的某个setOpn()方法),则会全局更改,因为只有一个.
最好使枚举上的数据不可变.然后,对于变量选项,您可以ArrayList将具有选项的每个事物关联,并为其中一个枚举分配.
你可以这样做:
public class ThingWithOptionsAndEnum {
private final TestEnum myBaseOptions;
private final ArrayList<String> myAdditionalOptions = new ArrayList<>();
public ThingWithOptionsAndEnum(final TestEnum base, String... options) {
this.myBaseOptions = base;
if (options != null) {
for (String option : options) {
myAdditionalOptions.add(option);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
小智 8
此页面上的其他答案可能都是正确的,但可能无法帮助您解决问题.
而不是枚举,尝试实现一个普通的旧类,但包括一个clone()方法.然后,您可以创建该类的一些"默认"实例,每个实例代表一个默认产品配置.当用户选择某个产品配置时,您调用clone()主对象,然后您可以使用常规设置器从此处修改对象.
查看Prototype设计模式.整个想法是使用这些"主"对象来创建可以随后更改的新副本.我想这可能是你想要的更多. https://en.wikipedia.org/wiki/Prototype_pattern
不,枚举不适合描述相似但具有不同状态的对象.
枚举常量是静态的.您没有两个不同的实例TEST1.你只有一个.TEST2在您的示例中引用的两个列表条目都引用相同的实例.它不是副本,它是第二个参考.
要拥有相似但状态略有不同的实例,您应该声明一个类,而不是枚举.你可以使用一个枚举来形容变化的类型(例如COLOR_VARIATION,CUSTOM_LOGO).您可以有两个不同的类来扩展被调用的类Variation或直接使用它 - 取决于实现细节是否不同.但是,您将使用new Variation(...)或使用静态工厂方法来创建新实例Variation,然后,每个Variation实例的字段中可以有一组不同的值,即使它们都是相同的"变体类型".