Контроллер 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 без контроллера.

Другие вопросы по тегам