Zend Framework - Почему я должен использовать data mapper / Db_Table_Row? - PullRequest
22 голосов
/ 30 января 2011

Расширенный вопрос: Почему я должен использовать data mapper / Db_Table_Row, где DbTable способен выполнять большинство основных задач для манипулирования данными.

В настоящее время я изучаю 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@addr.com";
$user->save();

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

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

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

Ответы [ 2 ]

41 голосов
/ 30 января 2011

Вам не нужно определять свой собственный 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');
}

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

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

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

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

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

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

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

20 голосов
/ 30 января 2011

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

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

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

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

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

...