Поругайте... Делегат вместо if
От: /Forester/ Россия http://www.akteam.ru
Дата: 17.06.13 15:38
Оценка:
Всем привет!

Есть singleton, но с двухстадийным созданием. Типа такого:

class TwoPhaseSingleton
{
  static s_instance = new TwoPhaseSingleton();
  public static Instance { get { return s_instance; } }
  private TwoPhaseSingleton()
  {
  }

  public void Init() { ... }
}

// где-то на старте приложения...
TwoPhaseSingleton.Instance.Init();


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

Вторая фаза создания объекта может быть повторена через некоторое время и может пройти успешно.

Можно было бы отловить на старте приложения ошибку и повторить инициализацию через какой-нить sleep, но лень. Поэтому пошел ленивым путем, то есть при каждом обращении к экземпляру объекта проверять, что он инициализирован, и если нет, то выполнять инициализацию. Что-то типа такого:

  ...
  public static Instance 
  { 
    get 
    { 
      if(!s_instance.Initialized)
      {
        s_instance.Init();
      }
      return s_instance; 
    } 
  }
  ...


Но диспетчеризацию по if'ам не люблю. Мне более симпатичен такой вариант:

class TwoPhaseSingleton
{
  static s_instance = new TwoPhaseSingleton();
  public static Instance 
  { 
    get 
    { 
      s_instance.Init();
      return s_instance; 
    } 
  }
  private TwoPhaseSingleton()
  {
    Init = InitReal;
  }

  public Action Init { get; private set; }

  private void InitReal() { ...; Init = InitFake; }
  private void InitFake() { }
}


То есть Init — это не метод, а делегат. До инициализации в Init лежит функция, которая действительно выполняет инициализацию. После успешной инициализации в Init заносится пустая функция, которая ничего не делает.

Поругайте, сравните оба эти варианта. Какие есть плюсы и минусы?
Первый вариант очевиднее и понятнее для ООП. Второй ближе к ФП.
В первом варианте меньше расход памяти.
А что со скоростью выполнения?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.