Как распознать Active Record?

Там правда все через хитрые прокси все сделано, но чисто внешне все выглядит именно так.
в этом и отличие в doctrine ($user instanceof User) == false, а в tdbm true.
по идеи эта строка в DM выглядит так
PHP:
$userMapper->country($user)->getLabel();
$users = $countryMapper->users($country)

ps ($user instanceof User) == false тоже не лучшее решение
 
Эм, UserProxy extends User, так что вполне себе true
в этом случае UserProxy становится AR нет?

PHP:
class UserProxy extends User{
  private $mapper; // вот мы все и вшили
  use ProxyTrait;
}
не многим лучше чем
PHP:
class User{
  private $dao;
}
отделить хранилище от сущностей
 
этом случае UserProxy становится AR нет?
Нет, конечно, оно же не ходит само в базу
У АР достаточно четкое определение, зачем домыслы? Открываешь EAA и читаешь. Тоже и про ДМ. Там же в ДМ упомянут и LazyLoad, который тебя смущает.

отделить хранилище от сущностей
ну так сущность ничего не знает о хранилище как и о прокси, все происходит прозрачно
 
У АР достаточно четкое определение, зачем домыслы?
DM The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other.
AR An object carries both data and behavior. Much of this data is persistent and needs to be stored in a database.

на что намекаешь хоть?


Нет, конечно, оно же не ходит само в базу
тут тоже не User ходит а dao
PHP:
class User{
  private $dao;
}
 
Последнее редактирование:
LazyLoad - это такой performance hack.
Фактически для тебя UserProxy === User. UserProxy корреткно реализован и не нарушает LSP, а никто, кроме ORM, не знает о существовании UserProxy.
 
LazyLoad - это такой performance hack.
Фактически для тебя UserProxy === User.

я вот что понять не могу в этом случае

PHP:
// допустим
interface UserRepository {
  public function getCountry():Country;
}

class UserProxy extends User implements UserRepository{/*...*/}

// какой тип вы ожидаете
public function fx(/* тут*/ $user){
 $user->getCountry()->getLabel();
}
 
Да нет же, какой implements UserRepository?

PHP:
class User
{
    private $country;
    public getCountry(): Country
    {
        return $this->country;
    }
}
User $user = $userRepository->find(1);
Country $country = $user->getCountry();
$label = $country->getLabel(); // lazy load
А то, что $country это в каком-то случае на самом деле CountryProxy, меня абсолютно не волнует.
 
Опередили. Но в принципе, сама идея реализации в одном классе двух функционалов… попахивает.
Внутренний sanity check должен уже срабатывать на такое.
 
Это компромисс, как и любой performance hack.

В PHP хоть так можно сделать. Вот, скажем, в JS вообще никак не получится lazy load сделать, там promise никак не спрячешь.
 
@fixxxer,

Так это классический AR! Напиши сразу как ты new User запилишь

В DM нормально написать $mapper->create(new User(“foo”))
 
Где ты у меня AR увидел? Если тебя смутило отсутствие конструктора в User - он там подразумевается, каэш.

В моем примере ровно как во второй Доктрине (с поправкой на псевдокод).

Заметь, CountryProxy будет только в том случае, если я сконфигуировал lazy load маппинг. Если я этого не делал - там будет обычный Country.
 
Последнее редактирование:
Это компромисс, как и любой performance hack.

В PHP хоть так можно сделать. Вот, скажем, в JS вообще никак не получится lazy load сделать, там promise никак не спрячешь.
Возможно, я неточно выразился… попробую объяснить.
Если getCountry() - это метод User, то всё окей, и какой там LazyLoad - никого не покачивает.
Если getCountry - это метод UserRepository, который торчит наружу из UserProxy, вот это уже фигня, ибо
1. Те, кто знает о User, ничего не знают о UserRepository.
2. Те, кто всё таки знают, о UserRepository… а с какого, простите, хрена они о нем знают?
 
@fixxxer, дело в том что Country содержит метод getUsers() который на момент после setCountry должно содержать страну с коллекцией содержащей хотябы одного пользователя, помимо этого у пользователя кроме страны есть роли, трансакции, ... получается громоздкая система, которую сложновато построить, если только это не AR вездесущий.
@AnrDaemon, я всегда думал, что в сервисе пишут такие строки
PHP:
function rename( $id, $name ){
  $user = $this->repo->get($id);
  $user->rename($name);
  $this->repo->update($user);
}
 
дело в том что Country содержит метод getUsers()
Это еще зачем?

В моем примере User - это aggregate root.

Возможно, в каком-то другом bounded context-е Country будет aggregate root-ом, но это уже другой Country в другом неймспейсе, да и то чисто теоретически - на практике не вижу никакого смысла в таком агрегате, там, скорее всего, будет достаточно read model, которая заполняется из запроса с джойнами.
 
Последнее редактирование:
дело в том что Country содержит метод getUsers() который на момент после setCountry должно содержать страну с коллекцией содержащей хотябы одного пользователя, помимо этого у пользователя кроме страны есть роли, трансакции, ... получается громоздкая система, которую сложновато построить, если только это не AR вездесущий.
Это какой-то северный пушной лис…
 
Это еще зачем?.
Но они же это предлагают

и да со страной у пользователя просто, она одна, а если пользователь это aggregate то и без прокси обойтись можно,

в обратную сторону от страны к пользователям интереснее
 
Последнее редактирование:
1) да я уже не про них, у них не ORM, у них своего рода объектный DBAL с кодогенерацией
2) я ж не говорю, что нельзя, в любом DM можно, мне непонятно, зачем это может понадобиться с нормальными моделями, тем более в обе стороны сразу
 
Сверху