2011-01-30 1 views
22

Вопрос: Почему я должен использовать dataperper/Db_Table_Row, где DbTable способен обрабатывать большинство базовых задач для обработки данных.Zend framework - Почему я должен использовать dataperper/Db_Table_Row?

Я в настоящее время обучения ZF v1.11

Для управления базы данных, я создал DbTable для каждых таблиц. Например, таблица «users» представлена ​​Application_Model_DbTable_Users без дополнительных кодов.

При манипулировании данными, я могу использовать:

<?php 
$uTable = new Application_Model_DbTable_Users(); 
$newUid = $uTable->insert(array('name'=>'Old Name', 'email'=>'')); 
$user = $uTable->find($newUid)->current(); 

// Then I can use $user which is instance of Table_Row 
$user->name = "New Name"; 
$user->email = "[email protected]"; 
$user->save(); 

Мой вопрос, когда я должен был бы определить класс строк (при условии, Table_Row называется, как DataMapper в ZF-Tutorials)

// By, adding this to the DbTable class 
protected $_rowClass = 'Application_Model_User'; 

Каковы преимущества наличия класса Row для каждого объекта? Может ли кто-нибудь указать мне на лучшие практики для этого.

+0

http://stackoverflow.com/questions/373054/ - дает представление о том, что отправка электронной почты или изменение логики пароля может быть реализована в классе таблицы Row, которые являются специфическими для пользователя. –

ответ

41

Вам не нужно определять собственный Table_Row. Однако это может быть полезно во многих случаях, особенно если вы хотите определить некоторые конкретные методы или свойства для данной строки пользователя. Они также могут улучшить читаемость вашего кода.

Например в таблице пользователей случае, вы могли бы определить метод, называемый getFullName() в пользовательской строке пользователя, как:

public function getFullName() { 
    return $this->firstName . ' ' . $this->lastName; 
} 

Затем, когда вы получаете объект пользователя строки, чтобы получить полное имя пользователя, вы просто делаете:

$user = $uTable->find($newUid)->current(); 
$fullName = $user->getFullName(); 

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

public function getAddress() { 
    return $this->findParentRow('Application_Model_DbTable_Addresses'); 
} 

В этом случае вы получите объект Адрес строки для текущего пользователя следующим образом:

$user = $uTable->find($newUid)->current(); 
$addressRow = $user->getAddress(); 

Другой пример, возникнет необходимость создания пользовательских методов удаления или запуска. Предположим, вы хотите, чтобы вы не хотели удалять пользователя admin с помощью метода delete(). Затем вы можете перегрузить метод удаления из Zend_Db_Table_Row следующим образом:

public function delete() { 
     if ('admin' === $this->userRole) { 
       return 0; 
     } 
     return parent::delete(); 
} 

Таким образом, вы не сможете удалить пользователя с правами администратора только по телефону удалить() объекта пользователя строки:

$user = $uTable->find($newUid)->current(); 
$rowsDeleted = $user->delete(); // would be 0 if $user is admin 

Это всего лишь три основных примера, показывающих полезность определения ваших собственных классов строк. Но, конечно, они не нужны. Однако, по собственному опыту, они весьма удобны.

+0

Удивительный !!! Спасибо за код примера реальной жизни с объяснением: -] –

+0

+1 Действительно, очень приятно. –

+0

В ответе на вопрос # 373054 есть функция sendMailTo для пользователя, хорошо ли поддерживать функции, связанные с базой данных, в классе Db_Row? Где должна существовать такая бизнес-логика для пользователя? –

20

В двух словах: речь идет об изоляции.

Zend_Db_Table - это реализация шлюза данных таблицы. Он передает CRUD доступ к определенному представлению таблицы через один класс.Он обычно используется с Table Module, например. класс, который содержит бизнес-логику для записей, обрабатываемых шлюзом.

Zend_Db_Table_Row - это реализация Row Data Gateway Pattern. Здесь возвращаемые объекты выглядят точно так же, как и запись в базе данных, и они содержат бизнес-логику для работы с этими данными, но они не содержат логику для CRUD с таблицей, из которой они были (это будет ActiveRecord), но агрегируют их.

Строчные шлюзы данных в порядке, если у вас не слишком много object relational impedance mismatch. Как объект сохраняется в реляционной базе данных и как он должен выглядеть в объектном мире, часто бывают разные вещи. При использовании Domain Model ваши бизнес-объекты обычно структурируются по-другому, чем они хранятся в базе данных. Таким образом, вы не можете легко CRUD их из базы данных. Здесь DataMapper вступает в игру.

DataMapper берет на себя ответственность за сопоставление объектов домена с наборами записей и наоборот. Это упрощает ваше приложение, поскольку оно отделяет объекты домена от структуры базы данных. Он сохраняет их разделенными и дает вам больше гибкости в том, как моделировать оба уровня (постоянство и домен).