плюсы и минусы создания моей системы аутентификации одноэлементным классом

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


person Mythriel    schedule 30.03.2012    source источник
comment
Вероятно, вопрос к programmers.stackexchange.com   -  person DaveRandom    schedule 30.03.2012
comment
Есть ли плюсы? Синглтоны - это еще одно модное слово для обозначения глобальных объектов. Которые вы должны знать, это плохо.   -  person PeeHaa    schedule 30.03.2012
comment
да, я понимаю, но я провожу несколько тематических исследований и пытаюсь понять, почему такие фреймворки, как zend и kohana, используют синглтон для своего класса аутентификации   -  person Mythriel    schedule 30.03.2012
comment
Потому что они не следуют лучшим практикам.   -  person PeeHaa    schedule 30.03.2012
comment
Zend - плохой пример для чего угодно, это очень раздутый фреймворк, который каждый день теряет больше пользователей, чем получает. Zend - один из самых больших лицемеров в мире PHP, они настаивают на стандартизации и передовых методах, но сама структура Zend очень слаба, когда следует всем, кроме поверхностных стандартов.   -  person kingmaple    schedule 30.03.2012
comment
@Mythriel: честно говоря, в Singleton нет ничего плохого, и это хорошая концепция. Если кто-то скажет, что этот фреймворк zend не следует лучшим практикам, что ж, тогда он точно не сможет хорошо усвоить дизайн ООП.   -  person linuxeasy    schedule 30.03.2012
comment
@linuxeasy, если вы прокрутите вниз, вы увидите ссылку Clean Code Talks: Global State and Singletons. Нажмите здесь. Это может прояснить некоторые вещи.   -  person tereško    schedule 30.03.2012


Ответы (4)


Вот некоторые минусы:

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

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

Обновление:

Вот несколько видео, которые могут вас заинтересовать:

person tereško    schedule 30.03.2012
comment
как код привязан к имени класса? когда вы можете использовать фабричный метод, который может возвращать ссылку на ваш одноэлементный класс, а затем эту ссылку можно использовать с любым именем, которое вам нравится? - person linuxeasy; 30.03.2012
comment
@linuxeasy, тот факт, что вы даже используете шаблон фабричного метода, привязывает вас к имени некоторого класса. Когда вы пишете Auth::getInstance(), вы связываете свой код с классом Auth. Конечно, вы можете использовать абстрактную фабрику, но если вы передадите экземпляр фабричного класса вокруг своего кода, тогда он потеряет смысл наличия синглтона. Сама фабрика может гарантировать, что существует только один экземпляр объекта. - person tereško; 30.03.2012
comment
Проголосуйте за этого парня. Нам нужно здравомыслие в этой войне против синглтонов. - person kingmaple; 30.03.2012
comment
@linuxeasy, вы обычно имеете дело с синглтонами при тестировании через автозагрузку и / или создание псевдонима для класса. Но это чрезвычайно запутанный способ, потому что вы должны тестировать таким образом не только синглтон, но и все классы, которые к нему привязаны. - person tereško; 30.03.2012
comment
ваш Auth::getInstance() может оставаться в простой функции & get_instance () независимо от имени класса, верно? и что вы имеете в виду, говоря если вы передадите экземпляр фабричного класса в свой код, тогда он потеряет смысл иметь синглтон ?? как это заставляет его терять точку синглтона? - person linuxeasy; 30.03.2012
comment
@kristovaher: Лол .. также добавь меня к отрицательным голосам в твоей войне против синглтонов: D, тебе сложно создать хороший синглтон? :П - person linuxeasy; 30.03.2012
comment
@linuxeasy, основная цель синглтонов - обеспечить наличие только одного экземпляра объекта. Абстрактная фабрика делает то же самое, не полагаясь на глобальное состояние. - person tereško; 30.03.2012
comment
@linuxeasy, функция глобальной области видимости не является решением, потому что тестирование основано на полиморфизме. Чтобы протестировать единый код, вы должны его изолировать. Эта изоляция достигается путем внедрения фиктивного объекта. - person tereško; 30.03.2012
comment
@linuxeasy, начиная с php5, вам не нужно передавать объекты по ссылкам. В PHP4 вы написали: $foo = & $bar_object;. Если вы сделаете то же самое в PHP5, вы увеличите использование памяти скриптом. В PHP5 мы делаем то же самое с $foo = $bar_object;. Это потому, что передается только обработчик объекта. - person tereško; 30.03.2012
comment
@ tereško: там, где это логично, не использовать синглтон, не используйте его. Там, где логично использовать синглтон, нет ничего плохого в его использовании. А теперь не храните мне таких примеров. Я не говорю о том, чтобы писать в синглтоне все, что может нанести вред вашим модульным тестам, но там, где есть действительно большие объекты, и несколько экземпляров этих объектов могут создать проблемы с масштабируемостью, нет никакого вреда в использовании синглтонов! - person linuxeasy; 30.03.2012
comment
@linuxeasy - ваш аргумент примерно так же хорош, как аргумент некоторых парней для использования глобальных переменных и функций. Синглтон, по сути, представляет собой комбинацию этих двух. И отказ от использования синглтонов не вызовет проблем с масштабируемостью! - person kingmaple; 30.03.2012
comment
@kristovaher: какими бы ни были мои аргументы, но ваш - один из уникальных аргументов, которые я видел на SO. ваши строки lol cumon on, дайте этому парню голоса за мою личную ненависть к одиночкам: D - person linuxeasy; 30.03.2012
comment
@linuxeasy, в ООП нет логического места для использования синглтона. Сам синглтон является артефактом парадигмы процедурного программирования. Синглтон эффективно создает глобальную переменную, используя нотацию, имитирующую нотацию объектно-ориентированного программирования. - person tereško; 30.03.2012
comment
@ tereško - я не уверен, что linuxeasy открыта для этих аргументов. Я просто надеюсь, что обсуждение здесь было достаточно хорошим, чтобы убедить других, которые, возможно, читают это и не знают о недостатках синглтонов. - person kingmaple; 30.03.2012
comment
Я не понимаю, почему это нарушает LOD? потому что одноэлементный класс auth будет иметь единую ответственность - person Mythriel; 30.03.2012
comment
@Mythriel нарушение происходит не внутри синглтона, а когда его использует любой другой экземпляр класса. - person tereško; 30.03.2012
comment
почему другие классы должны использовать объект аутентификации? объект auth должен использоваться в моих контроллерах, помощниках действий или библиотеках, если я их сделаю, я бы не стал связываться с моими классами модели - person Mythriel; 30.03.2012
comment
@Mythriel, контроллеры обычно являются классами. - person tereško; 30.03.2012
comment
да, я знаю ... но я бы не стал привязывать свой класс аутентификации к моей модели предметной области, так что объединение его на уровне приложения не так уж и плохо, или нет? .. А как насчет аутентификации как службы? класс обслуживания для обработки аутентификации - person Mythriel; 30.03.2012
comment
@Mythriel, сервисы (аутентификация, почтовая программа и т. Д.) На самом деле являются частью слой модели. В любом случае, я не понимаю, почему вы пытаетесь доказать, что аутентификация как синглтон - это хорошо. Черт .. как это вообще попадает к вашим контроллерам? Разве вы не должны проверять авторизацию пользователей, прежде чем пускать их внутрь контроллера? И авторизация зависит от аутентификации .. что делает ее еще более ранней проблемой. - person tereško; 30.03.2012
comment
я не пытаюсь доказать, что синглтоны хороши ... они не ... просто хочу создать хороший класс аутентификации для своего приложения ... а авторизация и аутентификация - это 2 разных класса с разными ролями - person Mythriel; 30.03.2012

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

person AlexTheo    schedule 30.03.2012

Не выбирайте синглтон! Это не лучше, чем прославленное объектно-ориентированное пространство имен, на самом деле Синглтон почти так же плохо, как использование глобальных переменных, и лишь немного лучше, чем использование глобальных библиотек функций (которые в сам по себе тоже плохо). Созданный объект лучше отправить в свои классы.

Поскольку объекты PHP 5, передаваемые другим объектам, по умолчанию передаются по ссылке. Они не создают новый экземпляр (если не используют ключевое слово clone). Это позволяет передавать любую информацию о сеансе как объект другим объектам, которые в ней нуждаются.

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

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

person kingmaple    schedule 30.03.2012

В PHP объект не остается в памяти после завершения запроса.

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

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

  • Предотвращает создание нескольких избыточных экземпляров, что снижает использование памяти для запросов.

  • Распределяет одни и те же данные при множественном доступе.

Например: функция get_instance в Codeigniter является реализацией концепции Singleton, в соответствии с которой в каждом запросе используется только один экземпляр Codeigniter.

person linuxeasy    schedule 30.03.2012
comment
Как? Поскольку если вы создаете несколько объектов и добавляете к ним определенный объект (например, сеанс), то экземпляры этих объектов не создаются. По умолчанию он передает их по ссылке. Он использует тот же объект, если вы его не клонируете. Я не понимаю, как неиспользование синглтона вообще потребует больше памяти. - person kingmaple; 30.03.2012
comment
пожалуйста, не приводите CodeIgniter в пример хороших практик разработки - person tereško; 30.03.2012
comment
@ tereško: а почему ты так думаешь? - person linuxeasy; 30.03.2012
comment
@kristovaher: Ну, когда вы создаете объекты с помощью new, вы создаете полный экземпляр, тогда как если вы используете синглтон, остается единственный экземпляр, и только синглтон экономит память. - person linuxeasy; 30.03.2012
comment
@linuxeasy, потому что я читал источник CI .. а вы? - person tereško; 30.03.2012
comment
@linuxeasy - тогда вы не знаете, как устроены не-Singleton-фреймворки. Они передают объект вновь созданным объектам вместо использования 'new' (в любом случае я не знаю, кто бы разработал такую ​​систему ООП, new никогда не следует использовать, кроме как в начальной загрузке или через фабрику объектов). Они передаются по ссылке, не занимают больше памяти и не имеют недостатков, присущих синглетонам. И их легко проверить. - person kingmaple; 30.03.2012
comment
@ tereško: Конечно, я тоже читал исходный код CI, и я хотел бы, чтобы вы записали, что такого плохого вы нашли в коде CI? и был ли это вы единственный человек, который читал исходный код CI в этом мире? поскольку многие компании используют CI для очень тонкой структуры, которую он дает. - person linuxeasy; 30.03.2012
comment
@kristovaher: Речь идет об использовании singleton. Если ваша ООП-система уже спроектирована так, чтобы возвращать ссылки на ваш объект, тогда ваша ООП-система использует концепцию самого метода Singleton + Factory. Что вы пытаетесь доказать? когда ваш пример сам по себе синглтон? - person linuxeasy; 30.03.2012
comment
@linuxeasy Factory метод не предполагает синглтона. Я могу протестировать систему с помощью фиктивных классов, и у меня может быть несколько экземпляров объекта Session в моей системе. Это невозможно с синглтоном. Почти забавно, насколько тебе трудно это понять. - person kingmaple; 30.03.2012