Помогите мне удалить Singleton: поиск альтернативы

Какую технологию сервера Вы используете и есть ли конкретный продукт, который Вы используете для аутентификации?

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

10
задан Community 23 May 2017 в 12:25
поделиться

6 ответов

Если единственная цель попытки избавиться от синглтона - с точки зрения модульного тестирования, возможно, замена одноэлементный получатель с чем-то, что вы можете заменить в заглушке.

class QueueThreadMapBase
{
   //virtual functions
};

class QeueueThreadMap : public QueueThreadMapBase
{
   //your real implementation
};

class QeueueThreadMapTestStub : public QueueThreadMapBase
{
   //your test implementation
};

static QueueThreadMapBase* pGlobalInstance = new QeueueThreadMap;

QueueThreadMapBase* getInstance()
{
   return pGlobalInstance;
}

void setInstance(QueueThreadMapBase* pNew)
{
   pGlobalInstance = pNew
}

Затем в вашем тесте просто замените реализацию карты очереди / потока. По крайней мере, это немного больше раскрывает синглтон.

3
ответ дан 4 December 2019 в 03:39
поделиться

Некоторые мысли по поводу решения:

Почему вам нужно ставить в очередь уведомления для наблюдателей, которые были созданы в другом потоке? Я предпочитаю, чтобы объект просто уведомлял наблюдателей напрямую и возлагал на них бремя реализации поточно-безопасной реализации, зная, что Notified () может быть вызывается в любое время из другого потока. Наблюдатели знают, какие части их состояния необходимо защитить блокировками, и они могут справиться с этим лучше, чем объект или очередь .

Предполагая, что у вас действительно есть хороший причина сохранения очереди , почему бы не сделать ее экземпляром? Просто выполните queue = new Queue () где-нибудь в main , а затем передайте эту ссылку.

1
ответ дан 4 December 2019 в 03:39
поделиться

Что не так с помещением очереди внутри предметного класса? Для чего вам нужна карта?

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

class Subject
{
  // Assume is threadsafe and all
  private QueueMap queue;
  void Subscribe(NotifyCallback, ThreadId)
  {
     // If it was created from another thread add to the map
     if (ThreadId != This.ThreadId)
       queue[ThreadId].Add(NotifyCallback);
  }

  public NotifyCallBack GetNext()
  {
     return queue[CallerThread.Id].Pop;
  }
}

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

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

1
ответ дан 4 December 2019 в 03:39
поделиться

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

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

0
ответ дан 4 December 2019 в 03:39
поделиться

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

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

Что касается фабрики приложений, которую описывает Мишко Хевери В его статье самые большие преимущества заключаются в том, что 1) фабричный подход не скрывает зависимости и 2) отдельные экземпляры, от которых вы зависите, недоступны глобально, так что любой другой объект может вмешиваться в их состояние. Таким образом, используя этот подход в любом заданном контексте приложения верхнего уровня, вы точно знаете, что использует вашу карту. С глобально доступным синглтоном любой используемый вами класс может делать неприятные вещи с картой или с картой.

0
ответ дан 4 December 2019 в 03:39
поделиться

Как насчет добавления метода Reset, который возвращает синглтон в его начальное состояние, которое вы можете вызывать между тестами? Это может быть проще, чем заглушка. Можно было бы добавить общий метод Reset к шаблону Singleton (удаляет внутренний одноэлементный pimpl и сбрасывает указатель). Это может даже включать реестр всех синглтонов с основным методом ResetAll для их сброса!

0
ответ дан 4 December 2019 в 03:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: