我正在尝试制作图书馆。我的代码中有一些常量,它们是某种不同的时间延迟和整个代码中的某些String值。我可以将它们提取到一个单独的常量类中,以得到
Delays.LENGTH_SHORT
(似乎更干净)
它们链接到库代码中的许多不同类。
现在,手头的问题是要从调用方使用者对其进行配置(即,如果使用者提供了值,则使用这些值,否则使用预设值)。从使用者的角度来看,我决定使用Builder模式来创建配置并将其传递到库模块的init
中(这仅在其生命周期中发生一次)。
是否有一种方法可以保留上述语法,但仍可以接受使用者的配置(设置仅在init
期间配置一次,对于所有其他时间,它的行为完全相同)?
从文件读取似乎很昂贵。
答案 0 :(得分:0)
对于只能从一组固定值中获取值的常量,则始终最好使用Java枚举而不是整数或字符串或其他原始数据类型。在一段时间内,他们更好地理解和维护。理想情况下,应从属性文件中读取默认值以对其进行初始化。但是,正如您在案例中提到的那样,出于性能原因,您希望避免从文件中读取数据。设计问题始终是开放性的,可以有多种方法。我推荐的一种方法如下:
public interface Configuration {
public Continent getContinent(); //For fixed set of values use enum
public Integer getPoolSize(); //If the config can take any value then use the corresponding data type directly
public String getDefaultLabel();
}
public enum Continent {
ANTARTICA, AFRICA, ASIA, AUSTRALIA, EUROPE, NORTH_AMERICA, SOUTH_AMERICA;
}
public class ConfigurationBuilder {
private DefaultConfiguration configurationInstance;
private class DefaultConfiguration implements Configuration {
//Ideally the below values should be read from a property file, instead of hard coding it here.
private Integer poolSize = Integer.valueOf(50);
private String defaultLabel = "DEFAULT";
private Continent continent = Continent.ASIA;
@Override
public Continent getContinent() {
return continent;
}
@Override
public Integer getPoolSize() {
return poolSize;
}
@Override
public String getDefaultLabel() {
return defaultLabel;
}
}
public ConfigurationBuilder withContinent(Continent continent) {
this.configurationInstance.continent = continent;
return this;
}
public ConfigurationBuilder withPoolSize(Integer poolSize) {
this.configurationInstance.poolSize = poolSize;
return this;
}
public ConfigurationBuilder withDefaultLabel(String defaultLabel) {
this.configurationInstance.defaultLabel = defaultLabel;
return this;
}
public Configuration build() {
return this.configurationInstance;
}
public ConfigurationBuilder() {
this.configurationInstance = new DefaultConfiguration();
}
public static Configuration buildDefaultConfiguration() {
return new ConfigurationBuilder().build();
}
}
public class Library {
private Configuration configuration;
public void init(Configuration configuration) {
this.configuration = configuration;
}
public void init() {
this.configuration = ConfigurationBuilder.buildDefaultConfiguration();
}
private Library(Configuration config) {
this.init(config);
}
private Library() {
this.init();
}
/**
* Library is not singleton here.
*
*/
public static Library getInstance(Configuration configuration) {
return new Library(configuration);
}
public static Library getInstance() {
return new Library();
}
}
public class Client {
public static void main(String args[]) {
Configuration config = new ConfigurationBuilder()
.withContinent(Continent.AFRICA)
.withPoolSize(20)
.withDefaultLabel("Label")
.build();
Library lib = Library.getInstance();
lib.init(config);
}
}
请检查Library和Client类的用法。 -它使用了Builder模式。 -它具有init()和init(Configuration)方法,以允许完全依赖库的默认设置。 -ConfigurationBuilder支持提供部分或全部配置值以覆盖 -当前所有三个配置选项都是可重写的-大陆,poolSize和defaultLabel。但是,如果某些配置是Library专用的,则只需从Builder中删除该属性的withXXX方法。
希望这符合您的需求。好问题!