2010-04-23 2 views
3

Я понимаю важность Dependency Injection и его роль в тестировании единицы, поэтому следующий вопрос дает мне паузу:PHP ООП: Избегайте Singleton/Статические методы в модели предметной области Pattern

Одной из областей, где я бороться не для использования Singleton используется шаблон Identity Map/Unit of Work (который содержит вкладки в состояние объекта домена).

//Not actual code, but it should demonstrate the point  

class Monitor{//singleton construction omitted for brevity 
    static $members = array();//keeps record of all objects 
    static $dirty = array();//keeps record of all modified objects 
    static $clean = array();//keeps record of all clean objects 
} 

class Mapper{//queries database, maps values to object fields 
    public function find($id){ 
     if(isset(Monitor::members[$id]){ 
     return Monitor::members[$id]; 
    } 
    $values = $this->selectStmt($id); 
    //field mapping process omitted for brevity 
    $Object = new Object($values); 
    Monitor::new[$id]=$Object 
    return $Object; 
} 

$User = $UserMapper->find(1);//domain object is registered in Id Map 
$User->changePropertyX();//object is marked "dirty" in UoW 

// at this point, I can save by passing the Domain Object back to the Mapper 
$UserMapper->save($User);//object is marked clean in UoW 

//but a nicer API would be something like this 
$User->save(); 

//but if I want to do this - it has to make a call to the mapper/db somehow  
$User->getBlogPosts(); 

//or else have to generate specific collection/object graphing methods in the mapper 
$UserPosts = $UserMapper->getBlogPosts(); 
$User->setPosts($UserPosts); 

Любые советы о том, как вы можете справиться с этой ситуацией?

Мне было бы жалко передавать/генерировать экземпляры доступа к карте/базе данных в сам объект домена для удовлетворения DI - В то же время, избегая этого, возникает множество вызовов внутри объекта домена для внешних статических методов.

Хотя я предполагаю, что если я хочу, чтобы «сохранить» было частью его поведения, в его построении требуется средство для этого. Возможно, это проблема с ответственностью, объект домена не должен быть обременен экономией. Это довольно аккуратная функция из шаблона Active Record - было бы неплохо каким-то образом реализовать ее.

ответ

1

Что я делаю, хотя, может быть, и не самый лучший способ действий, заключается в том, чтобы иметь четкое соглашение об именах для моих классов, FI: user_User является объектом домена, а user_mapper_User - это картограф.

В моем родителе domainObject класс I закодировал логику, чтобы найти ее картограф.

Затем у вас есть несколько вариантов делегирования ему, очевидно, будет использовать метод __call() в domainObject.

+0

Конечно, вот как я это делаю. Проблема заключается в следующем: создаете ли вы экземпляр NEW, или вы делаете статический вызов в mapper (учитывая, что пользовательский картограф должен существовать уже для того, чтобы он был пользователем), который существует вне Пользователя? Если вы вызываете новый картограф, вам, вероятно, нужно будет вызвать новый дескриптор БД, а также ссылку на Единицу работы и ID-карту ... - тогда как у внешнего класса уже установлено все это – sunwukung

+0

Я хранил дескриптор DB (в моем случае MDB2) static в родительском классе сопоставления, поэтому, независимо от того, сколько экземпляров ящика карт у меня есть, все они имеют один и тот же дескриптор. –

+1

Ах, теперь я вижу, это образец класса Monostate, не так ли? – sunwukung

Смежные вопросы