Проблемы с шаблоном "одиночка"

Ошибка ясно говорит, что пытается искать файл в LINUX как структура "/home/seluser/videos /" , который не будет доступен на окнах.

при запуске zalenium Он ищет dashboard.html в диске монтирования. Без этого файла панель инструментов не будет видима .

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

 docker run --rm -ti --name zalenium -p 4444:4444 ^
      -v /var/run/docker.sock:/var/run/docker.sock ^
      -v /c/Users/your_user_name/temp/videos:/home/seluser/videos ^
      --privileged dosel/zalenium start

документация Zalenium

46
задан Ankur 8 September 2009 в 06:37
поделиться

7 ответов

В среде сборки мусора это может быть проблемой в отношении управления памятью

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

Это большая проблема для языков, где у вас есть сборщик мусора (например, Java, Python и т. Д.), Потому что сборщик мусора всегда будет верить что нужен синглтон. В C ++ можно обмануть, удалив указав указатель. Тем не менее, это открывает собственную банку с червями, потому что она должна быть синглтоном, но, удалив ее, вы даете возможность создать вторую.

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

В многопоточной среде это может вызвать узкие места и вызвать проблемы синхронизации.

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

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

Головная боль от предполагаемого тестирования.

Примечательно, что конструктор синглтона может быть протестирован только один раз. Вам необходимо создать совершенно новый набор тестов, чтобы снова протестировать конструктор. Это нормально, если ваш конструктор не принимает никаких параметров, но как только вы примете параметр, вы больше не сможете эффективно использовать единичный тест.

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

(И это тоже ведет к плохому дизайну!)

Синглтоны также являются признаком плохого дизайна. Некоторые программисты хотят сделать свой класс базы данных одноэлементным. "

38
ответ дан 26 November 2019 в 20:19
поделиться

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

Есть ссылки на пару других статей о синглтонах того же автора.

30
ответ дан 26 November 2019 в 20:19
поделиться

При оценке шаблона синглтона вы должны спросить: «Какая альтернатива? Возникли бы те же проблемы, если бы я не Не используете шаблон Singleton? "

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

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

Возникнут ли те же проблемы в не- одиночный случай? Давайте рассмотрим их один за другим:

  • Управление памятью : Большой глобальный объект будет существовать при запуске приложения, и объект будет существовать до выключения. Поскольку существует только один объект, он будет занимать ровно столько же памяти, что и одноэлементный случай. Использование памяти не является проблемой. (@ MadKeithV: Порядок уничтожения при завершении работы - это другая проблема).

  • Многопоточность и узкие места : всем потокам потребуется доступ к одному и тому же объекту, независимо от того, был ли им передан этот объект в качестве параметра или вызывали ли они MyBigGlobalObject.GetInstance () . Так что синглтон или нет, у вас все равно будут те же проблемы с синхронизацией (которые, к счастью, имеют стандартные решения). Это тоже не проблема.

  • Модульное тестирование : если вы не используете шаблон Singleton, вы можете создать большой глобальный объект в начале каждого теста, и сборщик мусора уберет его когда тест завершится. Каждый тест будет начинаться с новой чистой среды, на которую не повлиял предыдущий тест. В качестве альтернативы, в случае синглтона, один объект проходит ВСЕ тесты и может легко стать «зараженным». Так что да, шаблон Singleton действительно кусает , когда дело доходит до модульного тестирования.

Мое предпочтение: из-за одной только проблемы модульного тестирования я стараюсь избегать шаблона Singleton. Если это одна из немногих сред, где у меня нет модульного тестирования (например, уровень пользовательского интерфейса), то я мог бы использовать синглтоны, в противном случае я их избегаю.

шаблон Singleton действительно кусает , когда дело доходит до модульного тестирования.

Мое предпочтение: из-за одной только проблемы модульного тестирования я стараюсь избегать шаблона Singleton. Если это одна из немногих сред, где у меня нет модульного тестирования (например, уровень пользовательского интерфейса), то я мог бы использовать синглтоны, в противном случае я их избегаю.

шаблон Singleton действительно кусает , когда дело доходит до модульного тестирования.

Мое предпочтение: из-за одной только проблемы модульного тестирования я стараюсь избегать шаблона Singleton. Если это одна из немногих сред, где у меня нет модульного тестирования (например, уровень пользовательского интерфейса), то я мог бы использовать синглтоны, в противном случае я их избегаю.

22
ответ дан 26 November 2019 в 20:19
поделиться

Мой главный аргумент против синглтонов состоит в том, что они сочетают в себе два плохих свойства.

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

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

Синглтон, как определено GoF, имеет два свойства:

  • Он доступен глобально и
  • Он предотвращает когда-либо экземпляров класса более одного раза.

Первый должен быть простым. Глобалы - это вообще плохо. Если вы не хотите глобального, то не нужно Мне тоже не нужен синглтон.

Вторая проблема менее очевидна, но, по сути, она пытается решить несуществующую проблему.

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

Когда вы в последний раз случайно набрали " std :: ostream () <<" hello world << std :: endl ", когда вы имели в виду " std :: cout <<" привет, мир << std :: endl "?

Этого просто не бывает. Так что нам не нужно , чтобы предотвратить это в первую очередь.

Но, что более важно, внутреннее ощущение, что «должен существовать только один экземпляр», почти всегда неверно.

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

Когда в последний раз вы случайно набирали " std :: ostream ( ) << "привет мир << std :: endl ", когда вы имели в виду " std :: cout <<" привет мир << std :: endl "?

Этого просто не бывает. Так что нам не нужно , чтобы предотвратить это в первую очередь.

Но, что более важно, внутреннее ощущение, что «должен существовать только один экземпляр», почти всегда неверно.

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

Когда в последний раз вы случайно набирали " std :: ostream ( ) << "привет мир << std :: endl ", когда вы имели в виду " std :: cout <<" привет мир << std :: endl "?

Этого просто не бывает. Так что нам не нужно , чтобы предотвратить это в первую очередь.

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

но «Я вижу использование только одного экземпляра» - это не то же самое, что «приложение выйдет из строя, если кто-то осмелится создать два экземпляра ».

В последнем случае одноэлементное значение может быть оправдано. но в первом случае это действительно преждевременный выбор дизайна.

Обычно нам требуется более одного экземпляра.

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

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

Или настройки программы. Конечно, одновременно может быть активен только один набор настроек. Но пока они активны, пользователь может войти в диалоговое окно «Параметры» и настроить второй набор параметров. Он еще не применил их, но как только он нажмет «ОК», их нужно поменять местами и заменить текущий активный набор. А это означает, что до тех пор, пока он не нажмет «ОК», на самом деле существуют два набора параметров.

И в более общем плане, модульное тестирование:

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

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

Так что, в конечном итоге, проблема с одиночными экземплярами не в том.

8
ответ дан 26 November 2019 в 20:19
поделиться

About this unit testing concern. The main problems seems to be not with testing the singletons themselves, but with testing the objects that use them.

Such objects cannot be isolated for testing, since they have dependencies on singletons which are both hidden and hard to remove. It gets even worse if the singleton represents an interface to an external system (DB connection, payment processor, ICBM firing unit). Testing such an object might unexpectedly write into DB, send some money who knows where or even fire some intercontinental missiles.

3
ответ дан 26 November 2019 в 20:19
поделиться

I agree with the earlier sentiment that frequently they're used so that you don't have to pass an argument all over the place. I do it. The typical example is your system logging object. I typically would make that a singleton so I don't have to pass it all over the system.

Survey - In the example of the logging object, how many of you (show of hands) would add an extra arg to any routine that might need to log something -vs- use a singleton?

1
ответ дан 26 November 2019 в 20:19
поделиться

I wouldn't necessarily equate Singletons with Globals. Nothing should stop a developer from passing an instance of the object, singleton or otherwise, as a parameter, rather than conjure it out of the air. The intent of hiding its global accessibility could even be done by hiding its getInstance function to a few select friends.

As far as the unit testing flaw, Unit means small, so re-invoking the app to test the singleton a different way seems reasonable, unless I'm missing something the point.

0
ответ дан 26 November 2019 в 20:19
поделиться
Другие вопросы по тегам:

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