Ste*_*all 34 java configuration design-patterns
我经常面临在内存中存储从文件系统上的文件加载的一些(可能很复杂的)配置设置的问题.我想知道是否有更好的方法来构建一个模式来解决这个问题,然而,比我一直在使用的那样.
基本上,我目前的解决方案涉及三个步骤.
建立一个单身人士.由于数据是持久的并且保证不会通过应用程序的运行时更改,因此只需要一个对象实例.
完成对对象的第一次请求后,创建对象并从文件读入.
用getter公开数据.
这有很多我的代码看起来像这样的效果:
MyConfiguration.getInstance().getWeightOfBomb()对我来说这看起来很奇怪.
是否有更好的方式以更加语义的方式处理这个问题?
noa*_*oah 34
依赖注入.您不一定要使用像Spring或Guice这样的DI框架,但是您确实希望避免使用单例乱丢代码.您仍然可以在实现中使用单例,但没有理由其余代码需要知道它是单例.单元测试和重构时,单身人士是一个巨大的痛苦.让您的代码引用一个接口.例如,
interface MyConfig {
double getWeightOfBomb();
}
class SomeClass {
private MyConfig myConfig;
public void doSomething() {
myConfig.getWeightOfBomb();
}
}
class MyConfigImpl implements MyConfig {
public double getWeightOfBomb() {
return MyConfiguration.getInstance().getWeightOfBomb();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用DI框架,只需设置类以MyConfig注入您的实现.如果你不这样做,那么仍然具有所有好处的最懒的方法是做类似的事情:
class SomeClass {
private MyConfig myConfig = new MyConfigImpl();
}
Run Code Online (Sandbox Code Playgroud)
真的,这取决于你.重要的是,myConfig当您稍后意识到需要改变行为和/或进行单元测试时,您可以在每个实例的基础上进行替换.
您可以创建一个接口来表示配置:
public interface Config {
interface Key {}
String get(Key key);
String get(Key key, String defaultValue);
}
Run Code Online (Sandbox Code Playgroud)
还有一个单例实现:
public enum MyConfig implements Config {
INSTANCE("/config.properties");
private final Properties config;
MyConfig(String path) {
config = new Properties();
try {
config.load(this.getClass().getResourceAsStream(path));
} catch (IOException | NullPointerException e) {
throw new ExceptionInInitializerError(e);
}
}
@Override
public String get(Config.Key key){
return config.getProperty(key.toString());
}
@Override
public String get(Config.Key key, String defaultValue) {
return config.getProperty(key.toString(), defaultValue);
}
public enum Key implements Config.Key {
PROXY_HOST("proxy.host"),
PROXY_PORT("proxy.port");
private final String name;
Key(String name) { this.name = name; }
@Override
public String toString() { return name; }
}
}
Run Code Online (Sandbox Code Playgroud)
然后在你的类中注入配置:
public class SomeClass {
private final Config config;
public SomeClass(Config config) {
this.config = config;
}
public void someMethod() {
String host = config.get(Key.PROXY_HOST);
String port = config.get(Key.PROXY_PORT, "8080");
// Do something
}
}
Run Code Online (Sandbox Code Playgroud)