Как я могу обеспечить согласованность данных, если значение установщика должно быть записано в файл? - PullRequest
1 голос
/ 07 апреля 2020

Я использую Preferences для хранения настроек приложения. Мой класс java читает настройки при запуске программы, а затем данные доступны с помощью простых методов получения для других классов.

Теперь я также хочу реализовать сеттеры, поскольку пользователь может изменять некоторые настройки в программе и, следовательно, вызывать Сеттер из другого класса java - это простой способ изменить настройки.

Если я изменю значение в моих настройках, как я могу убедиться, что данные в настройках и в классе согласованы? Стоит ли просто хранить данные в сеттере в объекте времени выполнения и в настройках?

И самое главное: как я могу убедиться, что не вызывается метод получения до того, как данные будут записаны в настройки? Как мне их синхронизировать?

Вот только очень простой пример для отображения проблемы:

private static final Preferences PREFERENCES = //here are valid preferences
private static final String KEY = //Some path to the attribute

private static PrefManager prefManager = new PrefManager();

private String serverIP;

private PrefManager() {
    this.serverIP = PREFERENCES.get(KEY, "");
}


public static void setServerIP(String serverIP) {
    // How do I synchronize the PREFERENCE object and this setter to prevent getter
    // calls between put and = call here?
    PREFERENCES.put(KEY, serverIP);
    prefManager.serverIP = serverIP;
}

1 Ответ

1 голос
/ 07 апреля 2020

С точки зрения решения вашей расы вы можете создать собственное расширение Preferences и добавить synchronized для установки и получения. Есть два способа создать расширение предпочтений: использовать карту внутри и скопировать все ключевые значения или создать фасад.

С точки зрения того, как вы поддерживаете свое приложение: Ответ на это Часть контроллера MVC

Пример фасада

Я скопировал все методы из Preferences и добавил их сюда. Вы можете видеть, что конструктор принимает параметр Preferences, который будет ссылкой, реализующей все методы в этом фасаде (см. Первые два метода absolutePath () и addNodeChangeListener (...) для примеров того, как это должно быть реализовано). обратите внимание, что методы put и get были синхронизированы. Поэтому, если какой-либо поток вызывает метод put, любой другой поток, вызывающий метод get, будет ждать, пока не будет завершен процесс put. (Возможно, вы захотите добавить синхронизированные и к другим методам)

==================

public class MyPrefsFacade extends Preferences {
    private Preferences p;

    public MyPrefsFacade(Preferences prefs) {
      p = prefs;
    }

    public String   absolutePath() { return p.absolutePath(); }
    public void addNodeChangeListener(NodeChangeListener ncl) { p.addNodeChangeListener(ncl); }
    public void addPreferenceChangeListener(PreferenceChangeListener pcl)
    public String[] childrenNames()
    public void clear()
    public void exportNode(OutputStream os)
    public void exportSubtree(OutputStream os)
    public void flush()
    public synchronized String  get(String key, String def)
    public boolean  getBoolean(String key, boolean def)
    public byte[]   getByteArray(String key, byte[] def)
    public double   getDouble(String key, double def)
    public float    getFloat(String key, float def)
    public int  getInt(String key, int def)
    public long getLong(String key, long def)
    public boolean  isUserNode()
    public String[] keys()
    public String   name()
    public Preferences  node(String pathName)
    public boolean  nodeExists(String pathName)
    public Preferences  parent()
    public synchronized void    put(String key, String value)
    public void putBoolean(String key, boolean value)
    public void putByteArray(String key, byte[] value)
    public void putDouble(String key, double value)
    public void putFloat(String key, float value)
    public void putInt(String key, int value)
    public void putLong(String key, long value)
    public void remove(String key)
    public void removeNode()
    public void removeNodeChangeListener(NodeChangeListener ncl)
    public void sync()
    public String   toString()
}
...