Обновлять все ссылки на объект при обновлении объекта (ссылка на ссылку) - PullRequest
1 голос
/ 16 января 2012

Я хочу объявить объект в Java, который похож на указатель на указатель в C ++, позвольте мне показать вам пример:

//*** At the application startup

//Initialize a settings container class
Settings settings = //Load settings 

//Declaring static Application class that contain a reference to the settings container
Application.setSettings(settings);

//Get sub settings from settings container class
DatabaseSettings dbSettings =  settings.getDbSettings();
LogSettings logSettings = settings.getLogSettings();

//Initialize components 
DatabaseConnector dbConn = new DatabaseConnector(dbSettings);
Logger logger = new Logger(logSettings);

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

//Update settings through Application static class 
Settings newSettings = //assign updated settings
Application.setSettings(newSettings);

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

dbConn      ---> settings.getDbSettings()
logSettings ---> settings.getLogSettings()

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

dbConn      ---> newSettings.getDbSettings()
logSettings ---> newSettings.getLogSettings()

Это как указатель на указатель ... Возможно ли это в Java? Как это можно сделать?

Ответы [ 3 ]

2 голосов
/ 16 января 2012

В Java у вас есть только ссылки на объекты.Чтобы иметь ссылку на ссылку, вам нужно какое-то косвенное обращение.Например,

AtomicReference<DatabaseSettings> refDatabaseSettings = new AtomicReference<DatabaseSettings>();

refDatabaseSettings.set(dbSettings);

DatabaseSettings dbSettings = refDatabaseSettings.get();

Вы можете передать ссылку и изменить ее в одном месте.Однако это не уведомит ни одну из ссылок, что она изменилась, просто позволит всем ссылкам видеть то же самое при следующей проверке.

2 голосов
/ 16 января 2012

Ну, вместо того, чтобы устанавливать новые настройки в приложении, обновите существующие.

Или просто задокументируйте тот факт, что эти настройки могут измениться, и что любой код, заинтересованный в наличии новых настроек, должен всегда проходить через Application.getSettings().

0 голосов
/ 16 января 2012

Вам нужно использовать какую-то форму системы уведомлений, чтобы выполнить то, что вы пытаетесь сделать. Наблюдатель / наблюдаемая или какая-то система, основанная на событиях, со слушателями, которые заинтересованы в изменениях, действительно единственный путь.

Вы, безусловно, могли бы создавать объекты настроек безопасности потока (например, DatabaseSettings), которые можно обновлять, и, следовательно, потребитель объекта получит новые значения, но это будет работать только в самых простых случаях. Проблема этого подхода заключается в том, что результаты нескольких обращений к экземпляру настроек станут противоречивыми. Предполагая, что в объекте настроек есть несколько параметров, которые связаны друг с другом, если один параметр получен, объект обновлен, а затем получен следующий параметр, у вас нет возможности узнать, что два вызова вызвали несогласованность ( друг другу) значения.

Например:

dbSettings.getConnectionUrl();
dbSettings.getUsername();

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

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

Это делает использование этих классов очень жестким и подверженным ошибкам.

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