2011-01-20 16 views
7

Wybrałem, aby pobrać plik właściwości w celu dostosowania niektórych ustawień. używam poniższy kod, żeby zarobić właściwości obiektu dostępny w klasieCzy właściwości Java są dostępne dla różnych klas?

Properties defaultProps = new Properties(); 
    try { 
     FileInputStream in = new FileInputStream("custom.properties"); 
     defaultProps.load(in); 
     in.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

muszę dodać do każdej klasy? Prawdopodobnie nie dlatego, że wtedy każda klasa otworzyłaby strumień do tego pliku. Ale nie jestem pewien, jak prawidłowo to znieść. Czy należy utworzyć klasę MyProperties i utworzyć instancję w dowolnej klasie potrzebnej właściwości?

Z góry dziękuję!

+0

Podobne odpowiedź: http: //stackoverflow.com/questions/4362911/how-to-create-a-singleton-class/4363254#4363254 – BalusC

Odpowiedz

10

Po zainicjowaniu defaultProps możesz udostępnić jego zawartość innym obiektom w aplikacji, np. poprzez publiczną statycznej metody akcesor, np:

public class Config { 
    private static Properties defaultProps = new Properties(); 
    static { 
    try { 
     FileInputStream in = new FileInputStream("custom.properties"); 
     defaultProps.load(in); 
     in.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    public static String getProperty(String key) { 
    return defaultProps.getProperty(key); 
    } 
} 

To najprostsze podejście, jednak stwarza dodatkową zależność, która sprawia, testów jednostkowych twardsze (chyba że dostarczenie sposobu w Config aby ustawić atrapa obiektu nieruchomości dla testów jednostkowych).

Alternatywą jest wstrzyknięcie defaultProps (lub poszczególnych wartości konfiguracyjnych z niego) do każdego obiektu, który tego potrzebuje. Może to jednak oznaczać konieczność dodania dodatkowych parametrów do wielu metod, jeśli hierarchie połączeń są głębokie.

+1

Nie podoba mi się to rozwiązanie. Stworzenie metody niestatycznej i stworzenie singletonu czyni go bardziej elastycznym i nic nie kosztuje. – maaartinus

+0

@maaartinus: jak precyzyjnie stosuje się wzór singletonowy? Czy nie mylicie tego z abstrakcyjnym wzorem fabrycznym? – BalusC

+1

@maaartinus, w jaki sposób Singleton uczyni to bardziej elastycznym? Zauważ, że praktycznie jest to już singleton (jest to unikalny obiekt globalny, z całym bagażem zależności), ukryty za interfejsem. –

0

Jest zbyt mało informacji, aby określić, jaki byłby najlepszy sposób na obsłużenie tego. Możesz odsłonić go za pomocą akcesora lub przekazać do każdej klasy, która tego wymaga. Alternatywnie możesz wyciągnąć właściwości wymagane przez każdą klasę i przekazać ich wartości do konstruktora klasy.

0

Załaduj właściwości raz i przechowuj właściwości, z których mogą pobierać inne klasy. Jeśli jest to klasa MyProperties, która odwołuje się do zmiennej statycznej gdzieś w porządku.

0

Jest to szczególny przypadek udostępniania wszystkiego na całym świecie. Używanie metod statycznych jest dość złe. Lepszym, ale złym rozwiązaniem jest użycie wzoru sigleton. Testowanie to największy problem. IMHO, najlepszym sposobem jest użycie Dependency injection, chociaż może to być przesada dla małych aplikacji.

3

Jeśli potrzebujesz tylko jednej instancji swojej klasy właściwości, możesz użyć singleton pattern.

To będzie wyglądać jak ta klasa:

public class MyProperties extends Properties { 
    private static MyProperties instance = null; 

    private MyProperties() { 
    } 

    public static MyProperties getInstance() { 
     if (instance == null) { 
      try { 
       instance = new MyProperties(); 
       FileInputStream in = new FileInputStream("custom.properties"); 
       instance.load(in); 
       in.close(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
       return null; 
      } 
     } 
     return instance; 
    } 
} 
+0

"this.load (in);" musi być "instance.load (in);" – icedek

+0

@icedek naprawiony (co za stara odpowiedź!) – SirDarius

0

Ponieważ informacja ta jest statyczna we wszystkich przypadkach, polecam realizacji klasę Properties jako singleton. Korzystając z metody staticinitialization block, możesz automatycznie załadować plik po uruchomieniu programu.

Nadal będzie potrzebny wewnętrzny mechanizm pamięci i mechanizm dostępu. Te powinny być również oznaczone jako static.

1

Dlaczego nie użyć statycznego zasobu ResourceBundle?

static final ResourceBundle myResources = 
      ResourceBundle.getBundle("MyResources", currentLocale); 
0

Zamiast ładowania właściwości w każdej klasie. Załaduj go gdzieś wokół main() i przekaż go innym klasom za pośrednictwem ich konstruktorów.

Nie udostępniaj ich na całym świecie. - Trudne do testowania - Przeciwko abstrakcji (Global Access, DAO mogą uzyskać dostęp do ustawień użytkownika należy zapobiegać poprzez przepuszczanie tylko to, czego potrzebuje .. nie wszystko). - Zajęcia leżą czego potrzebują

Powiązane problemy