Одиночные элементы: хороший дизайн или опора? [закрытый]

Вы можете пройти иерархию с рекурсивным CTE

. Это классический верхний вниз CTE:

WITH EmployeesHierarchy AS
(
    SELECT ID,[Level],Employee,Department,Code,MasterId
    FROM T_Employees
    WHERE [Level]=1
    UNION ALL
    SELECT nextLevel.ID,nextLevel.[Level],nextLevel.Employee,nextLevel.Department,nextLevel.Code,nextLevel.MasterId
    FROM EmployeesHierarchy AS recCall
    INNER JOIN T_Employees AS nextLevel ON nextLevel.[Level]=recCall.[Level]+1 AND nextLevel.MasterId=recCall.ID
)
SELECT * FROM EmployeesHierarchy
ORDER BY [Level],MasterId
GO

И теперь наоборот: я начинаю с упомянутых сотрудников в проекте и переместить список до тех пор, пока не будет родительского родителя больше. Данные проекта, полученные в первой части CTE, просто пройдены для отображения во всех строках.

WITH EmployeesHierarchy AS
(
    SELECT p.ID AS p_ID,p.ProjectId,e.ID AS e_ID,[Level],e.Employee,e.Department,e.Code,e.MasterId
    FROM T_Projects AS p 
        INNER JOIN T_Employees AS e ON p.EmployeeId=e.ID
    UNION ALL
    SELECT recCall.p_ID,recCall.ProjectId,nextLevel.ID,nextLevel.[Level],nextLevel.Employee,nextLevel.Department,nextLevel.Code,nextLevel.MasterId
    FROM EmployeesHierarchy AS recCall
    INNER JOIN T_Employees AS nextLevel ON nextLevel.ID=recCall.MasterId
)
SELECT * FROM EmployeesHierarchy
--WHERE ProjectId=456
ORDER BY [Level]

Результат

+------+-----------+------+-------+------------+------------+------+----------+
| p_ID | ProjectId | e_ID | Level | Employee   | Department | Code | MasterId |
+------+-----------+------+-------+------------+------------+------+----------+
| 3    | 23        | 1    | 1     | Thomas S.  | A          | 1-4  | NULL     |
+------+-----------+------+-------+------------+------------+------+----------+
| 2    | 456       | 3    | 1     | Simone S.  | A          | 1-3  | NULL     |
+------+-----------+------+-------+------------+------------+------+----------+
| 1    | 456       | 1    | 1     | Thomas S.  | A          | 1-4  | NULL     |
+------+-----------+------+-------+------------+------------+------+----------+
| 2    | 456       | 6    | 2     | Loris P.   | B          | 2-15 | 3        |
+------+-----------+------+-------+------------+------------+------+----------+
| 1    | 456       | 4    | 2     | Stefan K.  | B          | 2-18 | 1        |
+------+-----------+------+-------+------------+------------+------+----------+
| 3    | 23        | 4    | 2     | Stefan K.  | B          | 2-18 | 1        |
+------+-----------+------+-------+------------+------------+------+----------+
| 3    | 23        | 7    | 3     | Lennon I.  | B          | 2-19 | 4        |
+------+-----------+------+-------+------------+------------+------+----------+
| 1    | 456       | 8    | 3     | Kerim K.   | C          | 2-66 | 4        |
+------+-----------+------+-------+------------+------------+------+----------+
| 2    | 456       | 9    | 3     | Ilmas Y.   | C          | 2-59 | 6        |
+------+-----------+------+-------+------------+------------+------+----------+
| 1    | 456       | 10   | 4     | Innes Y.   | D          | 3-89 | 8        |
+------+-----------+------+-------+------------+------------+------+----------+
| 2    | 456       | 12   | 4     | Fatih O.   | I          | 3-32 | 9        |
+------+-----------+------+-------+------------+------------+------+----------+
| 3    | 23        | 11   | 4     | Andreas U. | E          | 3-63 | 7        |
+------+-----------+------+-------+------------+------------+------+----------+
67
задан Vaillancourt 6 June 2019 в 20:19
поделиться

23 ответа

В защиту одиночных элементов:

  • Они не так плохи как globals, потому что globals не имеют никакого осуществленного стандартом порядка инициализации, и Вы могли легко видеть недетерминированные ошибки из-за наивных или неожиданных заказов зависимости. Одиночные элементы (принимающий они выделяются на "куче"), создаются после всего globals, и в очень предсказуемом месте в коде.
  • Они очень полезны для ленивого ресурсом / - кэширующиеся системы , такие как интерфейс к медленному устройству ввода-вывода. Если Вы разумно создадите одноэлементный интерфейс к медленному устройству, и никто никогда не называет его, Вы не потратите впустую времени. Если другая часть кода называет его от нескольких мест, Ваш одиночный элемент может оптимизировать кэширование и для одновременно и избежать любых двойных поисков. Можно также легко избежать любого условия мертвой блокировки на управляемом одиночным элементом ресурсе.

Против одиночных элементов:

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

Мое собственное мнение:

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

56
ответ дан Peter Mortensen 24 November 2019 в 14:24
поделиться

Запишите нормальные, тестируемые, вводимые объекты и позвольте Guice/Spring/whatever обработать инстанцирование. Серьезно.

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

0
ответ дан Ben Hardy 24 November 2019 в 14:24
поделиться

Одна страшная вещь на одиночных элементах в, например, Java состоит в том, что Вы можете заканчивать с несколькими экземплярами того же одиночного элемента в некоторых случаях. JVM однозначно определяет на основе два элементы: полностью определенное имя класса и classloader ответственное за загрузку его.

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

0
ответ дан Asgeir S. Nilsen 24 November 2019 в 14:24
поделиться

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

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

Еще лучше, используйте инверсию контейнера управления! Большинство из них позволяет Вам разделять поведение инстанцирования от реализации Ваших классов.

0
ответ дан Nate Kohari 24 November 2019 в 14:24
поделиться

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

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

Тогда я создал singleton-класс, названный компания , который инкапсулировал все о месте, и это было абсолютно заполнено данными к тому времени, когда система была открыта.

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

Плюс, это была фиксированная, легкодоступная точка в масштабе всей системы для имения данных компании.

0
ответ дан Mario Marinato 24 November 2019 в 14:24
поделиться

Я использовал одиночные элементы набор времен в сочетании с Spring и не считал его опорой или ленивый.

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

В моем случае, одиночный элемент содержал клиентские критерии конфигурации - css расположение файла, критерии соединения дб, наборы функций, и т.д. - специфичный для того клиента. Эти классы инстанцировали и получили доступ через Spring и совместно использовали пользователи с той же конфигурацией (т.е. 2 пользователя от той же компании). * ** я знаю, что существует название этого типа приложения, но это выходит из меня*

, я чувствую, что было бы расточительно создать (тогда собирают "мусор"), новые экземпляры этих "постоянных" объектов для каждого пользователя приложения.

1
ответ дан Vinnie 24 November 2019 в 14:24
поделиться

Я нахожу, что необходимо быть очень осторожными [приблизительно 112], почему Вы решаете использовать одиночный элемент. Как другие упомянули, это - по существу та же проблема как использующий глобальные переменные. Необходимо быть очень осторожными и рассмотреть то, что Вы могли делать при помощи одного.

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

1
ответ дан Dan Herbert 24 November 2019 в 14:24
поделиться

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

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

1
ответ дан Jon Limjap 24 November 2019 в 14:24
поделиться

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

второе - то, что люди часто полагают, что ленивая инициализация с перепроверяемой блокировкой является хорошим способом реализовать их.

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

2
ответ дан Bill Michell 24 November 2019 в 14:24
поделиться

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

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

я вижу по крайней мере 3 набора классов, в которых я обычно разрабатывал бы, но я склонен одобрять меньшие более простые объекты, которые делают узкий набор задач очень хорошо. Я знаю, что это не природа большинства программистов. (Да я работаю над 5 000 чудовищ класса строки каждый день, и у меня есть специальная любовь к методам строки 1200 года, которые пишут некоторые люди.)

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

2
ответ дан Dan Blair 24 November 2019 в 14:24
поделиться

Singleton как деталь реализации прекрасна. Singleton как интерфейс или как механизм доступа является гигантский ЛАВАШ.

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

3
ответ дан MSN 24 November 2019 в 14:24
поделиться

Священные войны! Хорошо позвольте мне видеть.. В прошлый раз, когда я проверил, полиция дизайна сообщила..

Одиночные элементы плохи, потому что они препятствуют автоматическому тестированию - экземпляры не могут быть созданы заново для каждого тестового сценария. Вместо этого логика должна быть в классе (A), который можно легко инстанцировать и протестировать. Другой класс (B) должен быть ответственен за ограничение создания. Единственный Принцип Ответственности к носу! Это должно быть знание команды, что Вы, как предполагается, переходите через B к доступу - вид соглашения команды.

я соглашаюсь главным образом..

5
ответ дан Gishu 24 November 2019 в 14:24
поделиться

Я пытался думать о способе прийти к спасению плохого singelton сюда, но я должен признать, что это твердо. Я видел очень немного законного использования их и с текущим диском сделать внедрение зависимости andd поблочное тестирование, которое они просто тверды использовать. Они определенно - "грузовое культовое проявление " программирования с шаблонами разработки, я работал со многими программистами, которые никогда не взламывали книгу "GoF", но они знают 'Singelton', и таким образом они знают 'Шаблоны'.

я действительно должен не согласиться с Orion, хотя, большую часть времени я видел одиночные элементы oversused, это не глобальные переменные в платье, но больше как глобальные сервисы (методы) в платье. Интересно отметить, что, при попытке использовать Singeltons в SQL Server 2005 в безопасном режиме через интерфейс CLR, система отметит код. Проблема состоит в том, что у Вас есть персистентные данные вне любой данной транзакции, которая может работать, конечно, если Вы делаете переменную экземпляра только для чтения, можно обойти проблему.

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

5
ответ дан Dan Blair 24 November 2019 в 14:24
поделиться

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

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

6
ответ дан andreas buykx 24 November 2019 в 14:24
поделиться

Я думаю, что существует большое недоразумение об использовании Шаблона "одиночка". Большинство комментариев здесь называет его местом для доступа к глобальным данным. Мы должны быть осторожными здесь - Singleton, как шаблон не для доступа globals.

Singleton должна использоваться для имения только один экземпляр из данного класса. Репозиторий Шаблона имеет большую информацию о Singleton.

8
ответ дан Cem Catikkas 24 November 2019 в 14:24
поделиться

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

Erich Gamma сказал, что одиночный элемент является шаблоном, которого он желает, не был включен в книгу GOF, и это - плохой дизайн. Я склонен не соглашаться.

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

Недостатки:

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

Преимущества:

  • Один экземпляр класса представлен в любом данном моменте времени.
    • дизайном Вы осуществляете это
  • , Экземпляр создается, когда он необходим
  • , Глобальный доступ является побочным эффектом
19
ответ дан Chap 24 November 2019 в 14:24
поделиться
22
ответ дан Bleadof 24 November 2019 в 14:24
поделиться

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

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

26
ответ дан denis phillips 24 November 2019 в 14:24
поделиться

Google имеет Детектор Singleton для Java, которому я верю, начался как инструмент, который должен быть выполнен на всем коде, произведенном в Google. Причина ореховой скорлупы удалить Одиночные элементы:

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

Для более явного объяснения, видят' , Почему Одиночные элементы Спорны ' от Google.

37
ответ дан Brian 24 November 2019 в 14:24
поделиться

Одиночный элемент является просто набором глобальных переменных в маскарадном костюме.

Глобальные переменные имеют свое использование, также, как и одиночные элементы, но если Вы думаете, что делаете что-то прохладное и полезное с одиночным элементом вместо того, чтобы использовать yucky глобальную переменную (все знают, что globals являются плохим mmkay), Вы, к сожалению, введены в заблуждение.

31
ответ дан Orion Edwards 24 November 2019 в 14:24
поделиться

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

существует статический одиночный элемент , в который силы класса, что может только быть один экземпляр класса для каждого процесса (в Java на самом деле один на ClassLoder). Другая опция к [1 110], создают только один экземпляр .

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

Создание только одного экземпляра хорошо . Вы просто создаете один экземпляр, когда программы запускаются, и затем передайте указатель на тот экземпляр ко всем другим объектам, которым нужен он. Платформы внедрения зависимости делают это легким - Вы просто настраиваете объем объекта, и платформа DI будет заботиться о создании экземпляра и передаче его всем, кому нужен он. Например, в Guice Вы аннотировали бы класс @Singleton, и платформа DI создаст только один экземпляр класса (на приложение - у Вас может быть несколько приложений, работающих в той же JVM). Это делает тестирование легким, потому что можно создать новый экземпляр класса для каждого теста и позволить сборщику "мусора" уничтожить экземпляр, когда это больше не используется. Никакое глобальное состояние не протечет от одного теста до другого.

Для получения дополнительной информации: Чистые Переговоры по Коду - "Глобальное состояние и Одиночные элементы"

4
ответ дан Esko Luontola 24 November 2019 в 14:24
поделиться

Chicks dig me because I rarely use singleton and when I do it's typically something unusual. No, seriously, I love the singleton pattern. You know why? Because:

  1. I'm lazy.
  2. Nothing can go wrong.

Sure, the "experts" will throw around a bunch of talk about "unit testing" and "dependency injection" but that's all a load of dingo's kidneys. You say the singleton is hard to unit test? No problem! Just declare everything public and turn your class into a fun house of global goodness. You remember the show Highlander from the 1990's? The singleton is kind of like that because: A. It can never die; and B. There can be only one. So stop listening to all those DI weenies and implement your singleton with abandon. Here are some more good reasons...

  • Everybody is doing it.
  • The singleton pattern makes you invincible.
  • Singleton rhymes with "win" (or "fun" depending on your accent).
16
ответ дан 24 November 2019 в 14:24
поделиться

Я много читаю о "Синглтоне", его проблемах, о том, когда его использовать и т. Д., И вот мои выводы до сих пор:

  • Путаница между классической реализацией Синглтона и реальное требование: ИМЕТЬ ТОЛЬКО ОДИН ЭКЗЕМПЛЯР КЛАССА!

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

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

  • Не TDD . Если вы выполняете TDD, зависимости извлекаются из реализации, потому что вы хотите, чтобы ваши тесты было легко писать. Это делает вашу объектную модель лучше. Если вы используете TDD, вы не будете писать статический GetInstance =). Кстати, если вы мыслите объектами с четкими обязанностями, а не классами, вы получите тот же эффект =).

1
ответ дан 24 November 2019 в 14:24
поделиться
Другие вопросы по тегам:

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