Когда-то один товарищ убедил меня в том, что global vars — это нехорошо, и наплодил я уйму синглтонов на PHP5, создающихся по требованию и живущих, пока скрипт не скончается. В целом, весьма удобно.
Сейчас делаю сайтик, серверная PHPшная часть которого принимает и отдает по HTTP только XML (клиент на Flash). Захотелось мне покрыть unit-testами этот серверный XML-based API. Чтобы не запускать каждый тест через HTTP с внешними редиректами (долго и неэстетично), я должен либо отказаться от синглтонов, либо убивать их экземпляры ручками перед началом каждого теста, сбрасывая состояние приложения в "только что запущено":
class CSingleton {
...
function destroyInstance() {
UT::checkActive(); // throws if not in unit-testing mode
self::$__instance = NULL;
}
};
Оба варианта кажутся одинаково кривыми. Кроме того, не исключена ситуация, когда мне потребуется тестировать синглтон, а потом создавать его экземпляр как часть среды для тестов других классов.
В общем, выглядит все это так, что сингтоны — сакс. До сих пор не могу понять, куда ж мне ползти? Как осел буриданов... Подскажите плиз что-нибудь дельное.
И есть ли какие-нибдуь книги/статьи по поводу грамотной декомпозиции именно с точки зрения TDD?
ДГ>Сейчас делаю сайтик, серверная PHPшная часть которого принимает и отдает по HTTP только XML (клиент на Flash). Захотелось мне покрыть unit-testами этот серверный XML-based API. Чтобы не запускать каждый тест через HTTP с внешними редиректами (долго и неэстетично), я должен либо отказаться от синглтонов, либо убивать их экземпляры ручками перед началом каждого теста, сбрасывая состояние приложения в "только что запущено":
Чего-то я не понял откуда у тебя эта проблема вылезла, откровенно говоря. Хотя на PHP ничего сложного не писал и unit-тестированием не занимался, так что может быть просто от банального незнания вопроса.
В чем разница между использованием синглтон-класса в состоянии "только что запущенного" и "уже хотя бы один раз использованного"?
...Ei incumbit probatio, qui dicit, non qui negat...
Здравствуйте, Дм.Григорьев, Вы писали:
ДГ>Когда-то один товарищ убедил меня в том, что global vars — это нехорошо
Истину глаголет
ДГ>, и наплодил я уйму синглтонов на PHP5
И синглтоны не сильно лучше
ДГ>Сейчас делаю сайтик, серверная PHPшная часть которого принимает и отдает по HTTP только XML (клиент на Flash). Захотелось мне покрыть unit-testами этот серверный XML-based API. Чтобы не запускать каждый тест через HTTP с внешними редиректами (долго и неэстетично), я должен либо отказаться от синглтонов, либо убивать их экземпляры ручками перед началом каждого теста, сбрасывая состояние приложения в "только что запущено":
О, то есть ты уже это и сам понял.
ДГ>В общем, выглядит все это так, что сингтоны — сакс.
Ну не то чтобы совсем, но очень часто да.
ДГ> До сих пор не могу понять, куда ж мне ползти? Как осел буриданов... Подскажите плиз что-нибудь дельное.
Я ничего насчет PHP тебе посоветовать не могу, но в .NET, к примеру, используют каскадируемые IServiceProvider.
ДГ>И есть ли какие-нибдуь книги/статьи по поводу грамотной декомпозиции именно с точки зрения TDD?
Можно пока без TDD. GoF уже прочел?
... << RSDN@Home 1.2.0 alpha rev. 642 on Windows XP 5.1.2600.131072>>
ДГ>Сейчас делаю сайтик, серверная PHPшная часть которого принимает и отдает по HTTP только XML (клиент на Flash). Захотелось мне покрыть unit-testами этот серверный XML-based API. Чтобы не запускать каждый тест через HTTP с внешними редиректами (долго и неэстетично), я должен либо отказаться от синглтонов, либо убивать их экземпляры ручками перед началом каждого теста, сбрасывая состояние приложения в "только что запущено":
Зависит от синглтона, конечно, но можно попробовать их сериализовать, а перед запускам теста реинициализировать. Правда, будут теряться подсоединения к базе данных...
Здравствуйте, AndrewVK, Вы писали:
AVK>Можно пока без TDD. GoF уже прочел?
В процессе. Сожалею, что слишком поздно.
AVK>Я ничего насчет PHP тебе посоветовать не могу, но в .NET, к примеру, используют каскадируемые IServiceProvider.
Они соответствуют какому-либо порождающему паттерну в GoF?
Здравствуйте, Дм.Григорьев, Вы писали:
AVK>>Я ничего насчет PHP тебе посоветовать не могу, но в .NET, к примеру, используют каскадируемые IServiceProvider. ДГ>Они соответствуют какому-либо порождающему паттерну в GoF?
Нет, он несколько сложнее. В GoF только кирпичики. Самый близкий — абстрактная фабрика. Подробнее можно почитать здесь