Добавить сеттер в одноэлементный класс - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть одноэлементный класс, подобный этому

public class Service{

// SingletonHolder is a container class to hold singleton instance 
 private static final SingletonHolder<A> singleton = new SingletonHodler<>(new Service());

 private Service(){
}
  public static Service getInstance(){

//.instance() is a method in SingletonHolder to return singleton instance
    return singleton.instance();
  }

 //Method to start the Service class
  public void start(){
   // start the service
   // get the initial configuration and use the configuration value to speify a URL, something like:
   String initialConfiguration = Configuration.getSettings();
   TargetUrl = initialConfiguration.get.......
}

}

Другой класс для конфигурации.Этот класс инициализирует конфигурацию и использует configurationUpdate () для получения обновленного значения конфигурации.

public class Configuration{


    public void configurationInitialize(){

    // initialize the configuration and get the value
    initialConfigValue = ..........    
}


   // Method to update configuration
   public void configurationUpdate(){

   // some mehtod which will get the updated configuration value
   String updateConfiguration = .............

    }    
  //method to retrun configuration settings
  public static String getSettings(){.........}
}

Теперь я хочу сначала получить начальную конфигурацию.Затем получите обновленное значение, если конфигурация изменилась.

Один из моих вариантов - добавить метод установки в класс Service.И вызовите метод setter в методе configurationUpdate () класса Configuration, передайте этому параметру UpdateVlaue.

Я не уверен, что это правильный способ сделать это.Если я добавлю метод установки, это все еще одиночный?Будет ли эта операция вызывать какие-либо проблемы?Большое спасибо !!!

Редактировать: Другой класс инициализации вызовет класс конфигурации для инициализации конфигурации, а также вызовет Service.getInstance (). Start ()

1 Ответ

0 голосов
/ 09 февраля 2019

Я не уверен, что это правильный способ сделать это.Если я добавлю метод установки, это все еще одиночный?Будет ли эта операция вызывать какие-либо проблемы?

Это все еще будет синглтон.Если все потоки должны использовать один и тот же targetUrl, тогда все должно быть в порядке.Если каждый поток должен использовать свой собственный targetUrl, то установщик, изменяющий значение поля targetUrl, повлияет на все потоки.

Не уверен, что это то, что нужно, но, возможно, он даст некоторые полезные советы.

Вместо передачи конфигурации в экземпляр службы, сделайте ее доступной через ThreadLocal и статический метод, чтобы класс Service мог получить конфигурацию, когда она в ней нуждается (см. Переменную Configuration # settingsHolder и переменнуюКонфигурация # метод getSettings)

ПРИМЕЧАНИЕ. Я не использовал SingletonHolder, поскольку его назначение мне не совсем понятно (описанный способ не обеспечивает отложенную инициализацию и обычно используется держатель экземпляра).для отложенной инициализации)

public class Service {

    private static final Service INSTANCE = new Service();

    private static final ThreadLocal<TargetUrl> TARGET_URL_HOLDER = new ThreadLocal();

    private Service() {

    }

    public static Service getInstance() {
        return Service.INSTANCE;
    }

    public void start() {
        Settings initialConfiguration = Configuration.getSettings();
        TARGET_URL_HOLDER.set(initialConfiguration.getTargetUrl());
        // some more stuff before starting
    }

    public void reinitialize() {
        Settings updatedConfiguration = Configuration.getSettings();
        TARGET_URL_HOLDER.set(updatedConfiguration.getTargetUrl());
        .......
    }
}

public class Settings {
    private TargetUrl targetUrl;

    public TargetUrl getTargetUrl() {
        return this.targetUrl;
    }

    public void setTargetUrl(TargetUrl targetUrl) {
        this.targetUrl = targetUrl;
    }
}

public class Configuration {
    // use threadLocal to store the settings instance so it can be retrieved via a static method (e.g. getSettings)
    private static ThreadLocal<Settings> SETTINGS_HOLDER = new ThreadLocal<>();

    public void initialize() {

        // initialize the configuration
        Settings initialSettings = ..........
        SETTINGS_HOLDER.set(initialSettings);    
    }

    // Method to update configuration
    public void update() {
        // some method which will get the updated configuration value
       Settings updatedSettings = .............
       SETTINGS_HOLDER.set(updatedSettings);
    }

    //method to retrun configuration settings
    public static Settings getSettings() {
        return SETTINGS_HOLDER.get();
    }
}

public class Test {

    public static void main(String[] args) {
        Configuration configuration = new Configuration();
        configuration.initialize();

        Service service = Service.getInstance();
        service.start();
        // use service instance
        ...................

        configuration.update();

        service.reinitialize();

        // keep using the service instance
       .................
    }
}

В зависимости от случая использования, если все потоки должны использовать один и тот же targetUrl, он также может быть реализован с использованием статической переменной типа AtomicReference вместостатическая переменная типа ThreadLocal

...