2017-03-12 6 views
0

이 같은 파일에서 구성 매개 변수를 읽어야 자바 프로그램이 있습니다자바 : 상수에 액세스 할 수 있도록 어디서나

java -jar myapp.jar --config config.txt ... 

일단, 이러한 매개 변수를 변경하지 않고 프로그램의 모든 클래스에 접근 할 수 있어야한다로드를 .

이 매개 변수를없이 생성자 및 메서드에 매개 변수로 명시 적으로 추가하지 않고도 액세스 할 수 있습니까? 예를 들어 다음과 같이 할 수 있습니다.

public class Main { 

    public static void main(String[] args){ 

     // This list should be visible by any class 
     List<String> CONFIGS= readMyConfigsFromFile(args[0]);  
     ... 
    } 
} 

public class MyClass(){ 
    public MyClass(){ 
     String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main. 
     ... 
    } 
} 

public class MyOtherClass(){ 
    public MyOtherClass(){ 
     String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main. 
     ... 
    } 
} 
... 

이 모든 작업이 가능합니까? 그리고 그것은 할 수있는 권위있는 설정입니까? 그렇지 않다면 그것에 대해 권장 할만한 디자인은 무엇입니까?

는 (I 비슷한 질문을 읽었지만 내가 설명하는 상황에서 가능한 방법 경우 난 아직 확실 해요) 당신은 싱글 톤 패턴을 사용할 수

+0

https://www.mkyong.com/java/java- properties-file-examples/ –

+2

예. 클래스의 정적 인, 선호하는 마지막 필드를 구성합니다. https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html. 이렇게하면 유닛 테스트에 대한 코드 작성이 어려워지고 의존성 삽입을 사용하거나 생성자에서 전달하는 것이 좋습니다. –

+0

@Jonathan Portorreal 귀하의 링크가 여기 관련이 없다고 생각합니다. 나는 설정 파일을 읽는 법을 안다. 내가 가진 문제는 어디서나 콘텐츠를 볼 수있게 만드는 방법입니다. – dariober

답변

2

.

모델링하려면 구성에 문자열과 정수라는 두 개의 필드가 있다고 가정합니다.

public class Config { 
    private static Config INSTANCE; 

    private final String field1; 
    private final int field2; 

    public Config(String field1, int field2) { 
     this.field1 = field1; 
     this.field2 = field2; 
    } 

    public String getField1() { 
     return field1; 
    } 

    public int getField2() { 
     return field2; 
    } 

    public static Config getInstance() { 
     if (INSTANCE == null) { 
      INSTANCE = loadInstance(); 
     } 
     return INSTANCE; 
    } 

    private static Config loadInstance() { 
     // read your config from properties 
     String field1 = ... 
     int field2 = ... 
     return new Config(field1, field2); 
    } 
} 

그런 다음 Config.getInstance()을 사용하여 해당 인스턴스를 가져와야합니다.

이 구현에는 결함이 있습니다. getInstance()이 다른 theads에서 호출되면 여러 번 초기화 될 수 있습니다.

한 번만 초기화하는 것이 중요하다면이 결함을 극복하기 위해 이중 확인 잠금 https://en.wikipedia.org/wiki/Double-checked_locking을 사용할 수 있습니다.

0

"이것은 모두 가능합니까?" 예, 그렇습니다.

public class Config { 
private static final List<String> config = new ArrayList<String>(); 

public static void addConfig(String value){ 
    config.add(value); 
} 

public static List<String> getConfig(){ 
    return config; 
} 

}

당신이

public static void main(String[] args) { 
     //Read value from file here in some variable say configValue 
     Config.addConfig(configValue); 
} 

이 설정을

public class MyOtherClass(){ 
    public MyOtherClass(){ 
     Config.getConfig().get(0); // Do something with this conf param taken from Main. 
     ... 
    } 
} 

주에 액세스 할 수있는 config (설정)에 값을 추가하려면 당신은 자바에서 정적의 도움으로 그것을 할 쉽게 수 있습니다 위 코드는 스레드로부터 안전하지 않습니다. 동기화 개념을 추가하여 스레드를 안전하게 만들 수 있습니다.

이제 "할 수있는 것이 좋습니다?". 요구 사항에 따라 다릅니다. 언급 한대로이 값은 런타임을 변경하지 않으므로이 값을 사용할 수 있습니다. 그러나 초기화 된 후에는이 값을 "변경해서는 안된다"는 요구가 필요합니다. 응답이 달라지면 Singleton Pattern과 같은 것을 사용하고 객체가 생성 된 후에는 읽기만하고 쓸 수 없도록해야합니다. 또한 내가 제안한 것처럼 정적 메서드에서는 테스트가 정말 어렵다는 점에 유의하십시오.

1

이 솔루션은 다른 것과 마찬가지로 단위 테스트를위한 모의 객체가 필요합니다. 하지만 그것은 변하지 않는 객체에 인수를 캡슐화하는 것이 가장 좋습니다. 또한 스레드 안전성이 중요하지 않습니다.

public class Main { 

    public static void main(String[] args){ 

     new CONFIG(readMyConfigsFromFile(args[0]).toArray());    
     ... 
    } 

    public static final class CONFIG { 

     private final String[] args; 

     private static final CONFIG instance; 

     private CONFIG(String[] args) { 
      this.args = args; 
      instance = this; 
     } 

     public static CONFIG getInstance() { 
      return CONFIG.instance; 
     } 

     public String[] getArgs(){ 
      return Arrays.copy(this.args, this.args.length); 
     } 

     public String getArg(int index) { 
      return args[index]; 
     } 

} 

얻으려면 인수를 : 당신이 원하는 경우 대신 인덱스의 키 이들에 액세스하는 배열 대신 HashMap를 사용

Main.CONFIG.getArgs();