как передать объект класса в другой класс?

Alexandre

PHPПенсионер
я так и сделал:
скажи мне - зачем в твоем случае нужна Фабрика?
в общем случае (По Влиссидес http://www.books.ru/shop/books/8451) паттерн фабрика был задуман, чтоб можно было подключать (использовать) модули, имеющие одинаковый интерфейс, т.е. инстацировать класс по "имени" модуля.
по крайней мере, так он был задуман для использования на C++ или Java.
 

DevelopmentGuru

Новичок
triumvirat, ты короче не волнуйся.

Синглтоны пусть идут лесом. Понадобятся - добавишь. Ты задал вопрос про зависимости.

Да я просты пытаюсь понять, правильно ли ТАК фабрику использовать или нет.
Нет.

Тут тебе ребята всякую кашу в голову набили - а тебе нужно лишь направление дать для самостоятельной работы.

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

Увидь разницу между "зависимость от реализации" и "зависимость от интерфейса". Первое исправимо, второе - никогда. Чтобы убрать зависимость от реализации, используем контракт (читай, интерфейс). Соответственно, неодноклеточная версия фабрики должна возвращать контракт (интерфейс к неизвестной на стадии компиляции\интерпретации сущности).

Другой вопрос - так ли тебе это нужно в случае твоих User-ов? У тебя пока только один класс User (один интерфейс, одна реализация) и нутром чувствую, это не изменится. Изменится? Не поседеешь, реализовав фабрику и подправив 20 мест вызова. К этому времени у тебя будет чёткое видение о необходимости убрать зависимость. Причем это будет продиктовано не эстетикой, не выпендрежем перед ребятами, а исключительно текущей необходимостью. Дай себе время разобраться с этим вопросом, а пока не останавливайся - используй статическую зависимость!

Следующий шаг в деле зависимостей - т.н. Dependency Injection. Этот паттерн сформулирован самизнаетекем и опубликован 4 года назад тут: http://martinfowler.com/articles/injection.html. Полно реализаций и на PHP. Но опять же, тут уже я выпендриваюсь перед ребятами - поэтому если ты действительно интересуешься этим вопросом - дорожка указана.

все! и не парься..... Чем порще, тем лучше.
Мой ответ в унисон вышеприведенному лозунгу и твоей текущей ситуации: убери фабрику и создай "глобальную точку доступа" для DB (реестром ли, синглтоном ли, глобальной ссылкой ли - без разницы) - увидишь, дышать станет легче. А тем временем читай, читай, читай...
 

_Leonchik_

Новичок
DevelopmentGuru
А я с Вами СОГЛАСЕН.

-~{}~ 28.03.08 17:33:

triumvirat
когда я говорил про чес репы - это и имел в виду, что все горазды советовать, но а сами делают так как это им удобно в том или ином случае, но читать надо!

-~{}~ 28.03.08 17:34:

а все эти советы даже очень и нужны, кстати!
 

kvf77

Red Devil
Вы тут не рассматриваете вполне себе актуальную проблему - разработку через тестирование. Да, большинство из вас этим не парится, но всеже. Используя синглетон в конструкторе $db = ...GetInstance() вы зашиваете свой класс на этот синглтон. и более не имеете возможности АДЕКВАТНО его подменить. Передавая же готовый объект в конструктор __construct($db){...} вы получаете все преимущества. Во-первых, вы легко можете передать туда заглушку и протестировать свой класс, во-вторых, определенно имеется значительное поле для расширения, потому что вы можете расширять класс DB наследуясь от него, добавлять новые метода и так далее. Сингл-тон довольно неповоротливая конструкция и я не рекомендовал бы ею злоупотреблять.
 

Духовность™

Продвинутый новичок
да читал. перевариваю ещё.

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

DevelopmentGuru
спасибо

-~{}~ 28.03.08 20:28:

Alexandre
имеющие одинаковый интерфейс
исключительно одинаковый интерфейс? и ни шагу влево-вправо?
 

Alexandre

PHPПенсионер
исключительно одинаковый интерфейс? и ни шагу влево-вправо?
где-то так,
задается фабрика классов, например плагины цмс,
а вот какой модуль использовать - это мы узнаем на этапе исполнения.
пусть каждый модуль имеет метод run( что-то ), но для каждого класса своя реализация этого ран ( это разный функционал).
тогда мы имеем:
FactoryMod factoryMod= new FactoryMod;
IModule mod1 = factoryMod->getModule('page 1');
mod1->run();
...
IModule mod2 = factoryMod->getModule('page 2');
mod2->run();

в пхп это решается банально: $mod = new $ModuleName();
$mod -> run();
 

whirlwind

TDD infected, paranoid
ГЫ. Извиняюсь что не отписывался, болел неделю почти.

Вот честно говоря, ниче более бесполезного чем new $ModuleName() я придумать не смог. Проблема даже не в инстанцировании, то есть ежу понятно что написать new гораздо проще чем какие то там фабрики кудато там передавать. Проблема заключается в дальнейшей модифицируемости. Ваше new в конкретном месте не позволяет изменить процесс конструирования объекта БЕЗ ВМЕШАТЕЛЬСТВА в работающий код. Вся сила объектов в том, что мы его можем ПЕРЕДАТЬ объект неограниченной сложности как ОДНУ ПЕРЕМЕННУЮ. И как только мы перестаем передавать объекты, мы сразу теряем всю пользу от ООП.

Теперь по фабрикам. Декомпозиция системы облегчает работу с ее отдельными компонентами и позволяет заменять эти компоненты на уровне более мелких деталей. То есть на реальном примере: что проще поменять двигатель или бензонасос? Сама постановка - ЗАМЕНА ДЕТАЛЕЙ подразумевает, что никаких конкретных классов не должно создаваться на низких уровнях детализации. Но при сильной декомпозиции непременно встанет вопрос - как передать необходимые "запчасти" на более низкие уровни?

Лично для себя я вывел следующий подход. Разработка ведется ступенчато. То есть на определенном (более низком, детальном) уровне абстракции используется впрыск объектов. Как только количество впрыскиваемых запчастей становится слишком велико (что несомненно создает неудобства), имплементируется фабрика, на которую возлагается ответственность по созданию соответствующим образом настроенных экземпляров. Такие ступеньки повторяются до тех пор, пока код не достигнет уровня абстракции СИСТЕМА.

На примере это может выглядеть так

PHP:
$front = new FrontController(new MyControllerFactory(new MyValidatorFactory(),new MyDaoFactory()));
$front->dispatch(new HttpRequest($_REQUEST));
Таким образом, механизмы инстанцирования у нас сосредоточены в ограниченном количестве классов. И если мне нужно повесить логгер запросов на DAO я сделаю это прямо в точке входа вот так

PHP:
$front = new FrontController(new MyControllerFactory(new MyValidatorFactory(),new AttachLoggerDecarator(new MyDaoFactory())));
Управление кодом превращается в поворачивание одной ручки, а не откручиванию и закручиванию тысячи винтиков по всему проекту.
 

StUV

Rotaredom
whirlwind
все-таки не вижу разницы между подходами... да, с точки зрения подмены в тестировании - я соглсен с kvf77, но это старая проблема - каждый извращается как может

но даже в твоем примере тебе при необходимости подмены объектов в разных местах логики придется дописывать к FrontController методы впрыскивания дополнительных деталей
в сложной крупной "СИСТЕМЕ" - да, у тебя в одной точке сосредоточится весь "впрыск" - но в дебаге с ума сойдешь со всякими "is instance of" чтобы определить конкретный тип локального объекта

-~{}~ 03.04.08 18:55:

зы:
в крайности можно получить:
PHP:
FrontController::run(new AllThingsFactory());
и не париться ;)
 

whirlwind

TDD infected, paranoid
> придется дописывать к FrontController методы впрыскивания дополнительных деталей

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

> с ума сойдешь со всякими "is instance of"

type hinting и не париться

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

StUV

Rotaredom
тогда нет никакого дебага
у вас 100% покрытия функциональными и приемочными тестами?
круты =)

-~{}~ 03.04.08 19:07:

зы:
я не про теоретическую возможность существования идеального кода без _логических_ багов в сложных процессах, а про "будни программинга"
 

whirlwind

TDD infected, paranoid
> у вас 100% покрытия функциональными и приемочными тестами?

К сожалению нет, зато есть куда учиться дальше.

> а про "будни программинга"

А я похож на Фаулера? Спасибо, за комплимент :)
 

Gas

может по одной?
А я похож на Фаулера?
как знать, фоток я не видел ;)

стоит в коде покопаться для самообразования (с учётом того, что твои последние посты не являются для меня азбучными истинами) ?
 

StUV

Rotaredom
Gas
отсутствие смысла в "сравнении кода с опытом" приходит с опытом ;)

-~{}~ 04.04.08 01:24:

зы: код всегда обусловлен многими нетехническими факторами
 

whirlwind

TDD infected, paranoid
Gas ну, если хватит опыта отделить зерна от плевел, то несомненно стоит ;)
 

Gas

может по одной?
whirlwind, StUV
значит всё таки стоит покопаться, а вот насчёт отделения не уверен :)
 
Сверху