iiifx-production/lazy-init

This package is abandoned and no longer maintained. No replacement package was suggested.

LazyInit - lazy initialization helper

v1.0.3 2016-11-22 16:36 UTC

README

LazyInit - хелпер для быстрого создания методов ленивой(отложенной) инициализации.

SensioLabsInsight

Latest Version on Packagist Build Status Total Downloads

Отложенная (ленивая) инициализация (Lazy initialization) - приём в программировании, когда некоторая ресурсоёмкая операция (создание объекта, вычисление значения) выполняется непосредственно перед тем, как будет использован её результат. Таким образом, инициализация выполняется «по требованию», а не заблаговременно.

Классический пример использования:

class DeepThought
{
    protected $answer;

    public function getAnswer ()
    {
        if ( $this->answer === null ) {
            $this->answer = 42;
        }

        return $this->answer;
    }
}

$deepThought = new DeepThought();
echo $deepThought->getAnswer(); # 42

Аналогичный пример с использованием LazyInit:

class DeepThought
{
    use \iiifx\LazyInit\LazyInitTrait;

    public function getAnswer ()
    {
        return $this->lazyInit( function () {
            return 42;
        } );
    }
}

$deepThought = new DeepThought();
echo $deepThought->getAnswer(); # 42

Установка

Используя Composer:

$ composer require "iiifx-production/lazy-init:1.*"

Использование

LazyInitTrait содержит метод lazyInit() и свойство $lazyInitData, в котором буферизирует результаты вычислений. Предназначен для использования в объектах в динамическом контексте.

mixed lazyInit( Closure $container, string|array $dependency = null, array $params = [] )
  • $container - Closure-контейнер, содержащий в себе вычисления, должен вернуть результат.
  • $dependency - Строка, массив зависимостей или null - для сохранения результата вычисления. Если не указывать ключ, то он будет сгенерирован автоматически.
  • $params - Дополнительные данные, которые будут переданы в Closure-контейнер при его запуске.

LazyInitStaticTrait содержит метод lazyInitStatic() и свойство $lazyInitStaticData, в котором буферизирует результаты вычислений. Предназначен для использования в статических классах в статическом контексте.

mixed lazyInitStatic( Closure $container, string|array $dependency = null, array $params = [] )

Параметры метода аналогичны.

Методы способны автоматически генерировать ключ для буферизации данных основываясь на точке вызова в коде. Это реализуется с использованием функции debug_backtrace().

Примеры

Простой геттер:

class Lazy
{
    use \iiifx\LazyInit\LazyInitTrait;

    /**
     * @return string
     */
    public function getDate ()
    {
        return $this->lazyInit( function () {
            return date( 'd.m.Y' );
        }, __METHOD__ );
    }
}

$lazy = new Lazy();
echo $lazy->getDate(); # '12.07.2015'

Простой геттер с автоматическим созданием ключа:

class Lazy
{
    use \iiifx\LazyInit\LazyInitTrait;

    /**
     * @return string
     */
    public function getMicrotime ()
    {
        return $this->lazyInit( function () {
            return microtime( true );
        } );
    }
}

$lazy = new Lazy();
echo $lazy->getMicrotime(); # 1438928722.9734

Геттеры с зависимостью от входящих значений:

class Lazy
{
    use \iiifx\LazyInit\LazyInitTrait;

    /**
     * @param string $string
     *
     * @return mixed[]
     */
    public function parseString ( $string )
    {
        return $this->lazyInit( function () use ( $string ) { # Передаем параметр в замыкание напрямую
            return explode( ':', $string );
        }, [
            __METHOD__,
            $string,
        ] );
    }

    /**
     * @param int $timastamp
     *
     * @return string
     */
    public function formatTimastamp( $timastamp )
    {
        return $this->lazyInit( function ( $t ) {
            return date( 'd.m.Y', $t );
        }, [
            __METHOD__,
            $timastamp,
        ], [
            $timastamp # Передаем параметр как свойство
        ] );
    }
}

$lazy = new Lazy();
var_export( $lazy->parseString( 'A:B:C' ) ); # [ 0 => 'A', 1 => 'B', 2 => 'C' ]
var_export( $lazy->formatTimastamp( time() ) ); # '12.07.2015'

Использование в статических методах:

class LazyStatic
{
    use \iiifx\LazyInit\LazyInitStaticTrait;

    /**
     * @return string
     */
    public static function getDate ()
    {
        return self::lazyInitStatic( function () {
            return date( 'd.m.Y' );
        }, __METHOD__ );
    }
}

echo LazyStatic::getDate(); # '12.07.2015'

Использование хелпера за пределами классов:

use iiifx\LazyInit\LazyInitHelper;

function buildString( $array )
{
    return LazyInitHelper::lazyInit( function ($v) {
        return implode( '.', $v );
    }, 'build-string', [ $array ] );
}

echo buildString( [ 1, 5, 32 ] ); # '1.5.32'

Использование при создании одиночки(Singleton):

class Singleton
{
    use \iiifx\LazyInit\LazyInitStaticTrait;

    private function __construct () {}
    private function __clone () {}
    private function __wakeup () {}

    /**
     * @return static
     */
    public static function getInstance ()
    {
        return static::lazyInitStatic( function () {
            return new static();
        }, __METHOD__ );
    }
}
$instance = Singleton::getInstance();

Использование при создании пула одиночек(Multiton):

class Multiton
{
    use \iiifx\LazyInit\LazyInitStaticTrait;

    private function __clone () {}
    private function __wakeup () {}

    public $key;

    protected function __construct ( $key )
    {
        $this->key = $key;
    }

    /**
     * @param string $key
     *
     * @return static
     */
    public static function getInstance ( $key )
    {
        return static::lazyInitStatic( function ( $key ) {
            return new static( $key );
        }, $key, [ $key ] );
    }
}

echo Multiton::getInstance( 'master' )->key; # 'master'
echo Multiton::getInstance( 'slave' )->key; # 'slave'
echo Multiton::getInstance( 'master' )->key; # 'master'

Тесты

Build Status Code Coverage

Лицензия

Software License