我正在重新编写一些代码,并且已经确定了重新创建类的方式,因为存在固定数量的工作表,所以我将它们创建为枚举。这是基于构建器模式与伸缩构建器的可读性来做出的决定。
我获取的代码抓取了一些.xls文件,添加了标头(并从其他.xls文件中读取了一些标头),甚至还有一些子表。然后,它以特定方式将各种工作表合并在一起,以在主要excel工作簿上制作选项卡。我的问题是某些工作簿选项卡采用不同数量的工作表作为参数。我正在尝试应用构建器模式。这是我要编写的代码:
public enum workBookSheet {
mySheet1("Name1","mainSheet1.xls",true,1).addSubSheet("pathToSubSheet1.xls"),
mySheet2("Name2","mainSheet2.xls",true,2).addHeaderSheet("pathToHeaders.xls").addSubsheet("pathtoSubSheet2.xls");
private String tabName;
private String mainSheetName;
private Boolean available;
private Integer order;
private String subSheetName;
private String headerSheetName;
private workBookSheet(String tabName, String mainSheetName, Boolean available, Integer order){
this.tabName = tabName;
this.mainSheetName = mainSheetName;
this.available = available;
this.order = order;
}
public workBookSheet addSubSheet(String subSheetName){
this.subSheetName = subSheetName;
return this;
}
public workBookSheet addHeaderSheet(String headerSheetName){
this.headerSheetName = headerSheetName;
return this;
}
}
Java给我的错误似乎是在说Java希望我的枚举声明(以逗号分隔的“枚举构造函数”列表位于顶部)仅包含构造函数,而不包含其他方法。我可以将这些方法移至下面的“构建器”方法,而不会有所抱怨。
public void buildSheets(){
mySheet1.addSubSheet("pathToSubSheet1.xls");
mySheet2.addHeaderSheet("pathToHeaders.xls").addSubSheet("pathtoSubSheet2.xls");
}
这是在枚举上实现构建器模式的唯一方法吗?它确实需要我运行单独的方法,这并不太麻烦。IT确实确实觉得我正在打破模式(我想,如果可行的话,这并不是一件坏事。)
注意:我环顾四周,看看是否有人在SO或网络上的其他地方提出了这个问题。我发现的最接近的问题是有关枚举和工厂的问题,但这并不能完全回答我的问题。我也知道这不是构建器模式,因为我没有一个单独的类,该类随后接受创建新枚举的build()方法。我想这是我最初设计中问题的根源,但是我对Java还是比较陌生。
那么,是否有更好的方法在Java枚举上使用构建器模式?还是我“足够亲密”?
尽管它并不严格符合构建器模式,但简短的答案是肯定的。有点。
缺少的部分无法调用.build()
以实例化枚举常量,因为build()不能使用new
。但是您可以从构建器模式中获得很多好处。面对现实,您不能使用静态工厂方法,并且枚举常量的内联子类化很奇怪。
这是使用国家枚举的示例。
package app;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Set;
import static app.Language.*;
import static com.google.common.base.Preconditions.*;
enum Language {
ITALIAN,
ENGLISH,
MALTESE
}
public enum Country {
ITALY(new Builder(1, "Italy").addLanguage(ITALIAN)),
MALTA(new Builder(2, "Malta").addLanguages(MALTESE, ENGLISH, ITALIAN).setPopulation(450_000));
final private int id;
final private String name;
final private Integer population;
final private Set<Language> languages;
private static class Builder {
private int id;
private String name;
private Integer population;
private Set<Language> languages = EnumSet.noneOf(Language.class);
public Builder(int id, String name) {
checkArgument(!StringUtils.isBlank(name));
this.id = id;
this.name = name;
}
public Builder setPopulation(int population) {
checkArgument(population > 0);
this.population = population;
return this;
}
public Builder addLanguage(Language language) {
checkNotNull(language);
this.languages.add(language);
return this;
}
public Builder addLanguages(Language... language) {
checkNotNull(language);
this.languages.addAll(languages);
return this;
}
}
private Country(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.population = builder.population;
this.languages = builder.languages;
checkState(!this.languages.isEmpty());
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Nullable
public Integer getPopulation() {
return population;
}
public Set<Language> getLanguages() {
return languages;
}
}
如果您有构建常量的常用方法,甚至可以将静态工厂方法放入构建器中。
因此,它不是Bloch的构建器,但非常接近。
问题内容: 我正在使用Spring 3.0.x,并按照枚举单例模式进行实现。 最近,我们开始通过Spring收集这些类型,因此我需要在类中添加@Component。 收集方法是 完成此操作后,我观察到失败,原因是Spring无法初始化枚举类(这是可以理解的)。 我的问题是- 是否有其他方法可以将枚举类标记为bean? 还是我需要更改实施方式? 问题答案: 如果确实需要使用基于枚举的单例(尽管默认情
问题内容: 是否可以在Java枚举中使用,还是需要使用?在我的测试中,它始终有效,但是我不确定是否可以保证。特别是,在枚举上没有方法,因此我不知道是否有可能获得一个枚举,该枚举将返回不同于的值。 例如,这样可以吗: 还是我需要这样写: 问题答案: 仅需2美分:这是Sun发布的Enum.java的代码,并且是JDK的一部分:
问题内容: 我有一个枚举,看起来像 我想做类似的事情 我出于教学目的简化了该示例,但是对于我的实际示例而言,这对我真的很有用。我可以用Java做到吗? 问题答案: 是的Enum是Java中的类: 但是在您的真实系统中,由于有固定类型的动物,我也将其设为Enum。 还要注意,使任何实例变量也很重要。 您可以在Java Language Specification中 找到有关它的更多详细信息。
问题内容: 这是我要完成的工作,我有一个包含一些值的枚举的类,我想对该类进行子类化并向该枚举添加更多值。这是一个不好的例子,但是: 因此HexDigits.Digit包含所有十六进制数字。那可能吗? 问题答案: 不,这不可能。最好的办法是使两个枚举实现和接口,然后使用该接口代替枚举。所以:
问题内容: 该方法返回枚举实例的序数。 如何设置枚举的序数? 问题答案: 您无法设定。它始终是常量定义的序数。请参阅Enum.ordinal()的文档: 返回此枚举常量的序数(其在枚举声明中的位置,其中初始常量的序数为零)。大多数程序员都不会使用这种方法。它设计用于复杂的基于枚举的数据结构,例如EnumSet和EnumMap。 实际上-您不需要。如果要一些整数属性,请定义一个。
问题内容: 我使用枚举来使一些常量: OPEN值为零,但我希望它为100。可能吗? 问题答案: Java枚举不同于C或C ++枚举,它们实际上只是整数的标签。 Java枚举的实现更像类-甚至可以具有多个属性。 最大的区别是它们是 类型安全的 ,这意味着您不必担心将COLOR枚举分配给SIZE变量。 有关更多信息,请参见http://docs.oracle.com/javase/tutorial/j