Как получать другие объекты из основного объекта?

Духовность™

Продвинутый новичок
Как получать другие объекты из основного объекта?

Читаю я этого вашего Фаулера (в разделе про Datamapper), который говорит о том, что перед тем, как лезть в БД за очередной порцией данных, нужно проверить некую _коллекцию_, не находится ли нужный нам объект там.

Вопрос после пояснения.

Вот у меня такая архитектура: на определенную запись таблицы свой объект и меппер. Чаще всего каждое свойство объекта - это примитивный тип. Например:

PHP:
class Model_User
{
    protected $model_attributes = array
    (
        // ID пользователя в таблице 
        'id' => array('type'=>'int', 'db_element'=>FALSE, 'default_value'=>0),
        // ID города, в котором живет пользователь 
        'user_city_id' => array('type'=>'int', 'db_element'=>TRUE),
        // имя пользователя 
        'user_name' => array('type'=>'string', 'db_element'=>TRUE),
    );

   //...
}
допустим, добавляю я в этот класс метод getCity(), который должен возвращать объект типа город:

PHP:
class Model_User
{
    // ...
    
    public function getCity()
    {
        $city_mapper = new City_Mapper();
        return $city_mapper->findById( $this->user_city_id ); // return City_Model
    }
}
если я правильно понимаю Фаулера, то в коде метода getCity() должна стоять проверка, а не присутствует ли объект города с ID=$this->user_city_id в какой-то коллекции..

Вопрос: как эту коллекцию лучше устроить? А может и не надо никакой коллекции, а просто достаточно добавить в класс свойство $city_object, которое будет содержать объект, если он уже был ранее запрошен:

PHP:
class Model_User
{
    protected $city_object = NULL;
    
    public function getCity()
    {
        // если объект ещё не инстанцирован, лезем в базу
        if (NULL === $this->city_object) 
        { 
            $city_mapper = new City_Mapper();
            $this->city_object = $city_mapper->findById( $this->user_city_id );
        }

         return $this->city_object;
    }
}
Но это криво как-то.

В общем, жду полноценных расписанных ответов от местных гуру.
 

Fortop

Новичок
который говорит о том, что перед тем, как лезть в БД за очередной порцией данных, нужно проверить некую _коллекцию_, не находится ли нужный нам объект там.
Где? http://martinfowler.com/eaaCatalog/dataMapper.html

Можно поточнее привести вопрос?
Поскольку непонятно о чем речь, то ли о кеше, то ли о связанных объектах (например пользователь и адрес)
 

Fortop

Новичок
zerkms
Дело в том, что я вообще не читал Фаулера :) впрочем как и GoF.

Но, бегло, по описанию, Identity map это нечто вроде кеша для сущностей.

-~{}~ 25.03.10 05:58:

Кстати да, вот и фраза
Martin Fowler
Whenever you want an object, you check the Identity Map first to see if you already have it.
 

Духовность™

Продвинутый новичок

zerkms

TDD infected
Команда форума
triumvirat
а чо рассказывать - делай без фанатизма. сначала разрули без IM.
как понадобится кеширование - прикрутишь.
если орм нормально написан - тогда добавление/убирание его будет прозрачным для остального кода.

реализация IM - простая как валенок в общем случае.

orm::$IM[model_type][id]
 

Духовность™

Продвинутый новичок
не понял как он должен храниться, у меня же ORM не статический класс, ОРМ у меня просто классы для работы с определенными таблицами! Я не могу сделать статическое хранилище в этих классах!
 

zerkms

TDD infected
Команда форума
почему ты не можешь сделать статическое свойство?

PHP:
  public static function factory($model, $id = NULL)
  {
    if ($id)
    {
      if (!isset(self::$identity_map[$model][$id]))
      {
        if (!Cache::get(Cache_Key::orm_object($model, $id), self::$identity_map[$model][$id]))
        {
          self::$identity_map[$model][$id] = parent::factory($model, $id);
          self::$identity_map[$model][$id]->_cache_dirty = true;
        }
      }

      return self::$identity_map[$model][$id];
    }

    return parent::factory($model, $id);
  }
вот примерно так я похакал кохановский орм, добавив туда IM + кэш
 

Духовность™

Продвинутый новичок
zerkms
а куда надо IM помещать - в меппер или в модель? А может лучше в IM сделать независимым регистром?
 

zerkms

TDD infected
Команда форума
triumvirat
"по фаулеру" его надо помещать в UoW. в жизни у меня до UoW никогда не доходило и я его всегда оставляю в маппере, в виде статического массива.
 
Сверху