Цепочки объектов.

Crazy

Developer
Автор оригинала: whirlwind
Что касается сингельтона. Если Вы приведете другую "неклассическую" реализацию, при которой гарантированно существует один и только один экземпляр
В самом деле? В таком случае я хотел бы для начала взглянуть на классическую реализацию. :)

-~{}~ 25.05.07 22:56:

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

whirlwind

TDD infected, paranoid
Crazy да ладно Вам. Неужели заставите тыкать носом в мануал, где на конструктор устанавливается непубличный спецификатор доступа.

А что Вас в плане TDD не устраивает? Использование моков? Ну дак это тот еще вопрос, про моки то.
 

Crazy

Developer
...и все же я хочу исходник. А уж если он будет и под PHP4 работать, то вообще песня. Hint: проект, из-за которого я опять начал писать на PHP, делается под четверку. Требование клиента.

Но не настаиваю -- если только пятая версия, то для сокращения объема дискуссии я готов на это пойти.

Про моки -- да, верно. Хотя есть и другой нюанс. Но мы ведь не собираемся обсуждать реализации синглетонов, неприменимые в профессиональном программировании, не правда ли? :)
 

whirlwind

TDD infected, paranoid
[m]singleton[/m]

-~{}~ 25.05.07 23:46:

PS. 4, говорите. А какой Вам TDD на 4? Какой Вы юзаете фрейморк для тестирования? Древний PhpUnit чтоли? Вы уж определитесь, или ООП+TDD, или требования клиента.
 

Crazy

Developer
Автор оригинала: whirlwind
[m]singleton[/m]
whirlwind, там много кода. Приведи please, здесь тот, который отвечает описанным мной условиям.

Честно говоря, непонятен мотив, с которым дана эта ссылка. Если не хотелось связывать себя конкретным кодом и надоела эта дискуссия -- послал бы меня в гугл. И все закончилось бы сразу. Быстро и безболезненно. Как я уже говорил, насильное установление истины мне неинтересно. Я дискутирую только с теми, кто этого хочет.

PS. 4, говорите. А какой Вам TDD на 4? Какой Вы юзаете фрейморк для тестирования? Древний PhpUnit чтоли? Вы уж определитесь, или ООП+TDD, или требования клиента.
Непосредственно сейчас я использую SimpleTest. Но, признаться, я очень удивлен этим вопросом. Неужели реализация синглетона под PHP4 зависит от тестового фреймворка? А если бы у меня оказался свой, собственный фреймворк (я начинал именно так) -- что тогда?

И, признаться, я немного не понял, почему сочетение TDD и PHP4 вызвало такую бурную реакцию. Я за 4 с чем-то года TDD на PHP4 не заметил чего-то важного? Буду рад послушать про это. Еще не поздно меня спасти от самого страшного.
 

whirlwind

TDD infected, paranoid
Бук на работе оставил. На стационарном домашнем только игрушки, а я уже выпил вотки (т.е. отмазываюсь что скачивать и ставить софт лень). Посмотрите здесь например svn://svn.prolib.ru/trunk/classes/WCMF.php

По поводу 4, не спорю - симплтест вроде написано что поддерживает 4, но тут вопрос в самой 4, в ее возможностях. Специально под четверку сам никогда ничего не писал. Сейчас если сталкиваюсь, ничего кроме раздражения от необходимости писать процедурно не ощущаю - в основном гавнокод (отнюдь не потому что 4 плохая) по этому ни о каких серьезных рефакторингах речи быть не может. Собсно на сколько мне известна разница между 4 и 5, я не понимаю какой ООП м.б. на 4 - исключительно воображаемый, но это ИМХО совсем уже офтоп. Как Вы сами говорили, не будем обсуждать

>неприменимые в профессиональном программировании
 

Develar

Новичок
Как вам такая реализация?
PHP:
abstract class Singleton_core
{
	private static $instances;

	public function __construct()
	{
		$this->singleton();
	}

	protected function singleton()
	{
		if (isset(self::$instances[get_class($this)]))
		{
			throw new BadMethodCallException(dgettext(Registry_core::$Configuration->get('framework_domain', 'Localization_core'), 'Класс допускает лишь одно инстанцирование и он уже инстанцирован'));
		}
		else
		{
			self::$instances[get_class($this)] = true;
		}
	}

	public function __clone()
	{
		throw new BadMethodCallException(dgettext(Registry_core::$Configuration->get('framework_domain', 'Localization_core'), 'Клонирование запрещено'));
	}
}
Кто хочет быть одиночкой, наследует от этого класса.
 

whirlwind

TDD infected, paranoid
Develar статические свойства не наследуются, если мне память не отшибает. Так что с наследованием для синглтонов немного сложнее чем для обычных классов.
 

whirlwind

TDD infected, paranoid
Ну да, я заметил уже :) Что-то в этом есть, нужно будет попробовать.
 

dark-demon

d(^-^)b
Что касается сингельтона. Если Вы приведете другую "неклассическую" реализацию, при которой гарантированно существует один и только один экземпляр, тогда я готов согласиться, что не обязательно в классе.
кэширующая фабрика уже была? :)
что-то вроде
Код:
$db1= cobj('DBSingletonClass',$param1,$param2);
Собсно на сколько мне известна разница между 4 и 5, я не понимаю какой ООП м.б. на 4 - исключительно воображаемый, но это ИМХО совсем уже офтоп. Как Вы сами говорили, не будем обсуждать
а что не так с ООПом в четвёрке?
 

whirlwind

TDD infected, paranoid
Develar есть одна деталь, с таким синглтоном обязательно нужен тулкит или фасад. Если без них, то получается то же самое что global $DB_LINK так часто встречающийся сами знаете в каком коде. С другой стороны, если включить в этот класс getInstance, то для него потребуется аргумент, а это уже неудобно. Как правило, более одного сингельтона в проектах мне еще ни разу не приходилось использовать, по этому я наверное все-таки за классический вариант который "по ссылке" :) с вариантами естессно
 

Develar

Новичок
Я использую реестр, а в нем одиночки как статические свойства - Configuration, Request, Db и т. п. Что-то типа вырожденного загрузчика и диспетчера - в его роли как раз реестр.

У вас класс WCMF это одиночка, а где соединение с базой тогда? У него спрашивают - getConnectionManager? Ваша реализация чище и надежнее, статические члены под перегрузку в PHP не попадают, заставить передать именно IConnectionManager нельзя...

>> С другой стороны, если включить в этот класс getInstance, то для него потребуется аргумент
Кстати, в ECMA запрещен приватный конструктор и в AS 3 - flex - используется что-то типа
PHP:
private static var impl:IPopUpManager = Singleton.getInstance("mx.managers::IPopUpManager") as IPopUpManager
Не очень удобно.
 

whirlwind

TDD infected, paranoid
У вас класс WCMF это одиночка, а где соединение с базой тогда? У него спрашивают - getConnectionManager? Ваша реализация чище и надежнее, статические члены под перегрузку в PHP не попадают, заставить передать именно IConnectionManager нельзя...
Да, getConnectionManager дает обычный объект - фабрика подключений. Так легче тестировать - например заткнуть чем нибудь (моки не юзаю). Есть еще setConnectionManager. Можно перекрыть сам менеджер, либо декорировать коннекты (в понедельник покажу примеры). Вроде нигде нет ограничения на доступ к объектам иерархии, по крайней мере так планировалось. Почему нельзя передать IConnectionManager? Везде type hinting, если в setConn..Man.. нету, значит бага.

-~{}~ 26.05.07 01:18:

> Я использую реестр
ну да, или реестр

-~{}~ 26.05.07 01:21:

ЗЗЫ. Кстати, насчет сингельтона коннекта. А Вам не приходиось работать с несколькими БД одновременно? ;)
 

Crazy

Developer
Автор оригинала: whirlwind
Кстати, насчет сингельтона коннекта. А Вам не приходиось работать с несколькими БД одновременно? ;)
Это, кстати, частый нюанс при использовании синглетонов: очень часто их ошибочно применяют там, где нужен, в сущности, не единственный объект, а пул объектов с разными характеристиками.

Типичное использование в случае доступа к БД: вызывающий код запрашивает соединение из пула, передавая каждый раз набор параметров (например, база, логин, пароль, кодировка). Соединение с такими характеристиками либо достается из пула, либо, если такого там нет, автоматически создается. (Не путать с java.sql.DataSource -- у него другая логика).

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

ustas

Элекомист №1
Автор оригинала: dark-demon
я тоже имею эту дурную привычку делать цепочки :)
проблемы начинаются при отладке и рефакторинге, ибо приходится рвать цепочки, смотреть что кто выдал, а потом снова собирать в красивые цепочки...
xdebug не пробывал? рвать не приходится.
 

dark-demon

d(^-^)b
посмотрел демки... чуть не сташнило...

ps: моё замечание вообще-то касалось яваскрипта. в пхп я цепочки просто не использую как из соображений совместимости, так и из соображения удобства отладки.
если интересует - под пхп я использую такую штуку: http://dark-demon.jino-net.ru/dumptest/

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

syfisher

TDD infected!!
whirlwind
Crazy

Можно я в ваш спор влезу? Я как раз по этой теме готовил доклад на конфу. Слайды будут выложены думаю в течение 1-2 дней. Сам доклад я скорее всего размещу на wiki.agiledev.ru в разделе про ООП как в дополнение к статье .sid-а про dependency inversion.
 
Сверху