правильно ли я понял Lazy Load?

Духовность™

Продвинутый новичок
правильно ли я понял Lazy Load?

Суть вот в чем: у меня есть объект "Опрос" и этот объект должен содержать дочерние объекты - объекты типа "вариант ответа".
Вот я получаю свой объект через маппер:
PHP:
$vote = $mapper->findById(2);
и НЕ всегда нужно загружать объекты типа "вариант ответа". Следовательно, нужно обеспечить механизм, при котором объекты типа "вариант ответа" загружались в класс только тогда, когда это действительно необходимо.

Вот тут http://www.gotdotnet.ru/LearnDotNet/NETFramework/451426.aspx прочитал, что первоначально в системе создается пустой объект (Сотрудник), который не содержит в себе информации (Проекты), и, как только система пытается получить информацию, объект пытается ее загрузить.

Насколько я понял, Lazy Load должна сработать непосредственно в момент запроса данных:
PHP:
$vote->getQuestions(); // getQuestions должен загрузить данные типа "вариант ответа"
Так, да? А как мне поступить, если у меня объекты ничего не умеют запрашивать - этим занимаются исключительно мепперы?
Думаю, что нет иного варианта, как сделать в меппере метод загрузки вариантов ответов:
PHP:
$mapper->loadQuestions(&$vote);
Есть какие мысли?
 

Angerslave

Новичок
triumvirat
Дык запиши внутри $vote свой id (2), а при любом запросе данных (а не в методе findById) делай запрос в базу. Как это будет реализовываться - вопрос к твоей архитектуре.
 

Духовность™

Продвинутый новичок
вопрос к твоей архитектуре
архитектура такая: все запросы к БД делает маппер (или его подобие :))
доменные объекты не умеют и не знают ничего о существовании БД. поэтому и вопрос...
 

AmdY

Пью пиво
Команда форума
вот если он ща ещё накатит, то тогда он точно объяснит. я уже запасаюсь пивом, чипсами и занимаю место в кинозале.

не совсем понял про твой мэпер, но пока пиво впути, попытаюсь внести ясность. я так понимаю у тебя в мэпере прописаны связи, значит мэпер должен как-то узнать переданный объект и вытащить для него связи
$vote = $mapper->findVoteById(2);
$mapper->loadRelationQuestions($vote);
вобщем, понятно, что методы магические, а у $vote есть метод ->getName() который нужен для опозниния и выявления-подтягивание связаных сущностей.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
triumvirat
вопрос по существу: тебе нужна идеологическая верность концепции LazyLoad или у тебя есть реальная цель вроде "оптимизация производительности модуля Опрос"?

-~{}~ 07.02.09 11:18:

AmdY
магические методы необязательны, а в будущем они могут усложнить жизнь
 

HraKK

Мудак
Команда форума
triumvirat
Смотри то что сейчас ты делаешь, это ОРМ.
У тебя есть например обьект
vote()
В котором есть квестионс.
Ты делаешь обьект колекцию vote()
Например VoteCollection::getVote( 1 );
Он возвращает если есть обьект vote если нету инициализирует новый обьект vote - передав ему параметр id и не запуская ничего другого.
Дальше у тебя могут стречаться 2 задачи:
Получить название опроса ->title
И получить вопросы.
getQuestions()
В первом случае ты проверяешь если инициализированы данные опроса если нет отсылаешь запрос в свой маппер который вернет тебе данные. Во втором случае тебе не нужны данные самого опроса тебе надо вернуть коллекцию обьектов Question что ты и делаешь - проверяешь если такая колекция или нет, соответсвенно если есть возвращаешь если нету создаешь.
 

Духовность™

Продвинутый новичок
HraKKСпасибо, понятно. Только у меня оказывается контекст задачи немного иной.

Lazy Load подразумевает автоматическую загрузку. А у меня мапперы для того и нужны, что бы отделять мух отт котлет - объекты от БД. Если я сделаю автоматическую загрузку, то у меня в классе vote появится метод следующего содержания:

PHP:
public function loadQuestions()
{
    $questions_mapper = new Vote_Question_Mapper(); // меппер questions
    $params = array
    (
        'where' => array('id_vote = ?' => array($this->id))
    );
    $questions_list = $questions_mapper->getObjectList($params);

    foreach ($questions_list as $question_object)
    {
        $this->addQuestion($question_object);
    }
}
т.е. нарушается сама суть использования мапперов - объект vote теперь "знает" о существовании Vote_Question_Mapper.

По сути, решения два - либо позволят объекту знать о существовании меппера, либо загружать questions в vote руками:

$mapper->loadQuestions(&$vote);
 

HraKK

Мудак
Команда форума
Вот этот вот класс new Vote_Question_Mapper() и отделяет.
 

zerkms

TDD infected
Команда форума
public function loadQuestions()
{
if ($this->questions instanceof lazy) {
$this->questions = $this->questions->load();
}

return $this->questions();
}


простите за оформление кода - писал "на коленке" :)
 

zerkms

TDD infected
Команда форума
это критично. по возможности доменный объект ничего не должен знать о маппере - ему не должно быть важно, кто в него данные помещает при выборках и забирает для сохранения при обновлениях.
 

HraKK

Мудак
Команда форума
ой, я не правильно прочитал что там vote а там Questions
Делай как zerkms написал.

-~{}~ 09.02.09 12:40:

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

Духовность™

Продвинутый новичок
рекурсия в обсуждении?...

Делай как zerkms написал.
я что-то не понял, что он имеет в виду.

PHP:
public function loadQuestions()
{
    if ($this->questions instanceof lazy)
    {
        $this->questions = $this->questions->load();
    }

    return $this->questions();
}
это метод объекта Vote? $this->questions -- это что тако? Объект коллекции вопросов? У меня сейчас в объекте Vote содержится коллекция объектов questions в виде специфического объекта Object_List. Я могу Object_List расширить и сделать Questions_List и делать Questions_List->load() когда надо.

Но суть тажа остается - как метод load() организовать? )
 

HraKK

Мудак
Команда форума
Угу вот их и загружай когда они потребовались.
 

zerkms

TDD infected
Команда форума
$this->questions -- это что тако? коллекция вопросов, содержащаяся в Vote?
да

У меня сейчас в объекте Vote содержится коллекция объектов questions.
верно. в случае отложенной же загрузки, в том свойстве, где раньше хранилась коллекция в чистом виде - будет лежать объект класса lazy. как он прозрачно будет вызываться - я написал выше.

вкратце sample usage класса lazy может выглядеть как-то так:

$lazy = new lazy(array($this, 'findById'), array($this->id));

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

примерная реализация метода лоад:

lazy::load() {
return call_user_func_array($this->callback, $this->args);
}
 
Сверху