Сделать свойства Java доступными в разных классах? - PullRequest
11 голосов
/ 20 января 2011

Я решил взять файл свойств для настройки некоторых параметров. Я использую следующий код, чтобы сделать объект Properties доступным в классе

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

Должен ли я добавить это в каждый класс? Вероятно, не потому, что тогда каждый класс открыл бы поток для этого файла. Но я не уверен, как правильно с этим справиться. Должен ли я создать класс MyProperties и создать экземпляр класса, для которого нужны свойства?

Заранее спасибо!

Ответы [ 8 ]

12 голосов
/ 20 января 2011

После инициализации defaultProps вы можете сделать его содержимое доступным для других объектов в вашем приложении, например, через общедоступный статический метод доступа, например:

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);
  }
}

Это самый простой подход, однако он создает дополнительную зависимость, которая усложняет юнит-тестирование (если только вы не предоставите метод в Config для установки объекта фиктивного свойства для юнит-тестирования).

Альтернативой является добавление defaultProps (или отдельных значений конфигурации из него) в каждый объект, который в этом нуждается. Однако это может означать, что вам нужно добавить дополнительные параметры для большого количества методов, если иерархия вызовов глубока.

3 голосов
/ 20 января 2011

Если вам нужен только один экземпляр класса свойств, вы можете использовать шаблон синглтона .

Это будет выглядеть примерно так:

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;
    }
}
1 голос
/ 20 января 2011

Почему бы не использовать статический ResourceBundle?

static final ResourceBundle myResources = 
          ResourceBundle.getBundle("MyResources", currentLocale);
0 голосов
/ 17 января 2017

Вместо загрузки свойств в каждом классе. Загрузите его где-нибудь вокруг main () и передайте его другим классам через их конструкторы.

Не делись ими по всему миру. - Сложно проверить - Против абстракции (Глобальный доступ, DAO может получить доступ к настройкам пользователя. Его следует предотвратить, передавая только то, что ему нужно .. не все) - классы врут, что им нужно

0 голосов
/ 20 января 2011

Поскольку эта информация является статической для всех экземпляров, я рекомендую реализовать класс Properties как singleton . Используя static метод блока инициализации , вы можете автоматически загрузить файл при запуске программы.

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

  protected static void load(FileInputStream in) {
    // existing load functionality here
  }
}

Вам все еще понадобится внутренний механизм хранения и механизм доступа. Они также должны быть помечены static.

0 голосов
/ 20 января 2011

Это особый случай, когда все становится доступным в глобальном масштабе.Использование статических методов довольно плохо.Лучшее, но плохое решение - использовать шаблон sigleton .Тестирование - самая большая проблема здесь.ИМХО, лучше всего использовать Внедрение зависимостей , хотя это может быть излишним для небольших приложений.

0 голосов
/ 20 января 2011

Загрузите свойства, используя один раз, и сохраните свойства в тех областях, которые могут извлечь другие классы. Если это класс MyProperties, который ссылается на статическую переменную где-то, это нормально.

0 голосов
/ 20 января 2011

Слишком мало информации, чтобы определить, как лучше всего с этим справиться. Возможно, вы захотите выставить его, используя метод доступа, или передать его каждому классу, который этого требует. Кроме того, вы можете извлечь свойства, которые нужны каждому классу, и передать их значения в конструктор класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...