Контроллер Singleton Java
На днях я читал о синглетах и думал, что они будут реализованы в моем проекте, но мне не понравилось, как это выглядит логически, поэтому я создал то, что я бы назвал классом контроллера, чтобы управлять состоянием одиночный объект. Я хочу убедиться, что логика проверяется, и что я не случайно создаю дополнительные экземпляры.
//Controller for SaveSystem, allows the class to be created once for the
//duration of the application at the global level (believe this is called a
//singleton pattern)
public class SaveSystemContr {
private static SaveSystem saveSystemInstance;
public SaveSystem GetSaveSystemData() {
return saveSystemInstance;
}
public void SetSaveSystem(SaveSystem _saveSystem) {
if(saveSystemInstance!=null) {
saveSystemInstance=_saveSystem;
}
}
public static SaveSystem getSaveSystemInstance(final FirebaseAuth _auth, final LoadProjFragment _LFP) {
if(saveSystemInstance==null) {
saveSystemInstance = new SaveSystem(_auth, _LFP);
}
return saveSystemInstance;
}
public SaveSystemContr() {} //THE WAY IS SHUT!
}
Редактировать * Я не рассматриваю это как дубликат упомянутого вопроса, поскольку это была типичная / стандартная реализация синглтона, и в нем вообще используется другая модель с использованием контроллера для управления состоянием синглтона.
2 ответа
Я хочу убедиться, что логика проверяется, и что я не случайно создаю дополнительные экземпляры.
Похоже, вы можете создать столько экземпляров, сколько захотите:
SaveSystemContr controller = new SaveSystemContr();
// Create instance 1
controller.SetSaveSystem(new SaveSystem(auth, lfp));
// Create instance 2
controller.SetSaveSystem(new SaveSystem(auth, lfp));
// ...
Почему у вас есть метод установки, если вы хотите только 1 экземпляр?
Очень простой синглтон будет выглядеть так:
public final class SaveSystemSingleton {
// This class should only be accessed statically. Don't allow instance creation
private SaveSystemSingelton() {}
private static SaveSystem saveSystem;
// Encapsulate creation logic. Passing in params is misleading because
// all subsequent calls will do nothing with the params.
public static SaveSystem get() {
// If accessing from multiple threads do Double Check Locking instead!
if (saveSystem == null) {
saveSystem = new SaveSystem(new FirebaseAuth(), new LoadProjFragment());
}
return saveSystem;
}
}
Если вам действительно нужно передать параметры, определите отдельный метод статического установщика и сгенерируйте исключение, если оно вызывается более одного раза или если get()
вызывается без предварительного вызова установщика.
Кроме того, вы должны проверить внедрение зависимостей (например, Dagger2), что делает создание экземпляров объектов и определение их области видимости простым и понятным.
Сделайте конструктор приватным и удалите геттеры и сеттеры:
//Allows the OBJECT (not class) to be created once only
public class SaveSystem {
private static SaveSystem saveSystemInstance;
//make constructor private
private SaveSystem(final FirebaseAuth _auth, final LoadProjFragment _LFP) {
//todo complete constructor
}
public static SaveSystem getSaveSystemInstance(final FirebaseAuth _auth, final LoadProjFragment _LFP) {
if(saveSystemInstance==null) {
saveSystemInstance = new SaveSystem(_auth, _LFP);
}
return saveSystemInstance;
}
}
Как видите, его можно применять на SaveSystem
без контроллера.