• Главная
  • » PHP
  • » Внутреннее кэширование объекта класса

#1 2014.01.14 07:35

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Внутреннее кэширование объекта класса

Что то скучно на фаруме. Предлагаю вывести на обсуждение давно волнующую меня тему.
С этим вопросом начал сталкиваться с начала освоение ООП в PHP.
Есть определенный тип данных генерация которых занимает продолжительное время (База данных, чтение и запись файлов, получение данных с удаленного сервера и т.п.)
Задача такова при генерации данного объекта запретить его повторную генерацию этого самого объекта с целью оптимизации кода.
Есть вариант закрыть конструктор и сделать статический метод вызывающий внутри конструктор и возвращающий ссылку на объект: (Этот вариант отлично подходит в стого-типизированом языке)

Код:

1
lt;?class A { static private $listObject = array(); static public function &getObject($id) { if (isset(static::$listObject[$id])) return static::$listObject[$id]; else return static::$listObject[$id] = new A($id); } public $_id; public $_val; private function __construct($id) { $this->_id = $id; $this->_val = getDB($id); // getDB желательно вынесть в геттер но суть не в этом }}

Вроде архитектура данного обьекта и хорошая но есть один минус при оперировании с данными объекта, IDE не понимает что возвращает A::newObject($id) и не работает авто-завершение что сказывается на количестве багов и продуктивности написания кода.
тут приходить костыльная мысля делать это все в обычном конструкторе и в static::$list[$this->_id] писать $this и при повторном конструировании объекта с таким же ид будет происходить заполнение данных ссылками со статического списка.

Код:

1
lt;?class A { static private $listObject = array(); public $_id; public $_val; public function __construct($id) { $this->_id = $id; if (isset(static::$listObject[$id])) { $this->_val = &static::$listObject[$id]->_val; } else { $this->_val = rand(0, 100); static::$listObject[$id] = &$this; } }}

У меня еще есть надежда что можно как то иде научить определять тип переменной и юзать приватный конструктор

Неактивен

#2 2014.01.14 11:41

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Внутреннее кэширование объекта класса

Ну по первой части. Там явно напрашивается синглтон.
А чтобы IDE понимала тип переменной, добавь phpdoc типа /** @return A */

Неактивен

#3 2014.01.14 14:58

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Внутреннее кэширование объекта класса

Gemorroj
Блин а я крутил же доки. Завтыкал что в начале нужно было добавить две звездочки

Неактивен

#4 2014.01.14 15:41

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Внутреннее кэширование объекта класса

Gemorroj написал:

Там явно напрашивается синглтон

Ну синглтон как правило используеться для одиночной инициалицазии класса. У меня же обьектовм может быть множетство но основная задача что бы в памяти небыло два одинаковых обьекта

Неактивен

#5 2014.01.14 16:15

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Внутреннее кэширование объекта класса

а, не совсем правильно понял. ну почти то же самое. в новомодной терминологии это называется мультитон. и реализуется практически так же как у тебя в первом примере. за исключением того, что не понятно зачем там ссылочный метод и static.
я бы переписал так:

Код:

1
span style="color: #0000BB"><?phpclass A { static private $listObject = array(); protected $id; protected $val; static public function getObject($id) { if (isset(self::$listObject[$id])) { return self::$listObject[$id]; } return self::$listObject[$id] = new self($id); } private function __construct($id) { $this->id = $id; $this->val = getDB($id); // getDB желательно вынесть в геттер но суть не в этом }}

Неактивен

#6 2014.01.14 22:31

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Внутреннее кэширование объекта класса

Gemorroj написал:

за исключением того, что не понятно зачем там ссылочный метод и static.

а какая разница static::$listObject[$id] или self::$listObject[$id]? сейчас пересмотрю на self

Неактивен

#7 2014.01.14 23:25

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Внутреннее кэширование объекта класса

Неактивен

#8 2014.01.15 00:07

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Внутреннее кэширование объекта класса

Что то там ничего не понял. Но тесты показывают следующее
Я так понял:
parent - обращаемся к методу/свойству через класс родителя
self - обращается  методу через класс в котором был определен данный метод
static - обращаемся к методу через текущий класс
Добавлено спустя   5 минут  8 секунд:
Учитывая что я использую наследования получается что все же static будет целесообразнее использовать в данном случаее. В противном случае не важно будет self или static

Код:

1
lt;?abstract class TestVideo { static public $objectList; static public function &ID($id) { if (!isset(static::$objectList[$id])) static::$objectList[$id] = new static($id); return static::$objectList[$id]; } public $key; public $id; abstract protected function __construct($id);}class TestVideo1 extends TestVideo { static public $objectList = array(); protected function __construct($id) { $this->key = 'TestVideo1'; $this->id = $id; }}class TestVideo2 extends TestVideo { static public $objectList = array(); protected function __construct($id) { $this->key = 'TestVideo2'; $this->id = $id; }}$a = TestVideo1::ID('123');$b = TestVideo2::ID('1234');$c = TestVideo2::ID('123');//var_dump(array($a, $b, $c));var_dump(TestVideo::$objectList);var_dump(TestVideo1::$objectList);var_dump(TestVideo2::$objectList);

На выходе


NULL
array(1) {
  [123]=>
  object(TestVideo1)#1 (2) {
    ["key"]=>
    string(10) "TestVideo1"
    ["id"]=>
    string(3) "123"
  }
}
array(2) {
  [1234]=>
  object(TestVideo2)#2 (2) {
    ["key"]=>
    string(10) "TestVideo2"
    ["id"]=>
    string(4) "1234"
  }
  [123]=>
  object(TestVideo2)#3 (2) {
    ["key"]=>
    string(10) "TestVideo2"
    ["id"]=>
    string(3) "123"
  }
}

Или мои убеждения неверны?
А по поводу ссылочного метода. Я так полагал что бы объект не клонировался

Неактивен

#9 2014.01.15 23:38

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Внутреннее кэширование объекта класса

Gemorroj написал:

не понятно зачем там ссылочный метод

Ты прав я что то вообще запамятовал. Объекты же и есть ссылочный тип. передавал я не сам объект а ссылку на ячейку массива.

Код:

1
lt;?$a = A::getObject(123);$b =& A::getObject(123);var_dump(A::$listObject);$b = null;var_dump(A::$listObject);


array(1) {
  [123]=>
  &object(A)#1 (2) {
    ["id":protected]=>
    int(123)
    ["val":protected]=>
    int(598)
  }
}
array(1) {
  [123]=>
  &NULL
}

Неактивен

#10 2014.02.06 11:47

Nu3oN
Moderator
Откуда: БелгородЭ
Зарегистрирован: 2010.04.28
Сообщений: 805
Карма: 11
Профиль Веб-сайт

Re: Внутреннее кэширование объекта класса

сцка, темный лес! как же я сам себя запустил...


Я буду лучше голоден, но между креслом и рулем и на дороге.

Неактивен

  • Главная
  • » PHP
  • » Внутреннее кэширование объекта класса

Дополнительно

forum.wapinet.ru

PunBB Mod v0.6.2
0.011 s