php666
@php666
PHP-макака

Как идеологически правильно делать Lazy Load и делать ли её вообще?

Код на PHP.
class Category {
    public function getChilds(); // найти дочерние узлы
}


Вариант 1.
Ленивая загрузка в private свойство $childs.
Недостаток - при изменении потомков узла нужен механизм обновления $childs.
Причем этот механизм придется каждый раз писать руками, т.е. каждый раз заново делать в контексте объекта
$this->childs = null;
$this->childs = $this->getChilds() ;

в соответствующих методах, что очень не хочется.

Вариант 2.
Не делать lazy load, тогда во View я не могу делать что-то типа
<?php if ($category->getChilds() && $category->getChilds()->count()): ?>
        <div>
        <? foreach($category->getChilds() as $child): ?>
            <?=$child->name?>
        <? endforeach; ?>
        </div>
    <?php endif; ?>

- ибо будет каждый раз запрос к СУБД.

М.б. есть какие-то шаблоны проектирования по этому поводу, какие-то мысли?
Если кто разрабатывал подобные костыли, как вы писали?
  • Вопрос задан
  • 474 просмотра
Пригласить эксперта
Ответы на вопрос 1
@hello_my_name_is_dany
Backend Developer (Node.js, PHP, C#)
Есть магический метод __get (с двумя нижними подчёркиваниями)
class Category
{
    private $children = null;

    public function __get($property)
    {
        if ($property === 'children') {
            if ($this->children !== null) return $this->children;
            else {
                $this->children = $this->getChildren();
                return $this->children;
            }
        } else {
            throw 'Undefined property';
        }
    }

    private function getChildren()
    {
        // TODO: запрос к базе и получение результата
    }
}

$category = new Category();
someAction($category->children); // в первый раз будет запрос
showSubCategories($category->children); // второй и послудеющий раз возьмёт уже из приватного поля

А к вопросу нужности - зачастую в ORM это настраивается, какие поля брать сразу, а какие лениво. Так что полностью зависит от задачи.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы