2011-01-30 11 views
22

拡張質問:なぜデータマッパー/ Db_Table_Rowを使用する必要がありますか.DbTableはデータ操作のための基本タスクのほとんどを処理できます。Zendフレームワーク - なぜデータマッパー/ 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を仮定は、ZF-チュートリアルにDataMapperのと呼ばれる)

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

各エンティティにRowクラスを持たせることのメリットは何ですか?誰も私にこのベストプラクティスを指摘できますか?

+0

http://stackoverflow.com/questions/373054/ - 電子メールの送信やパスワードの変更ロジックは、ユーザー固有のテーブル行クラスで実装できるという考えを示しています。 –

答えて

41

独自のTable_Rowを定義する必要はありません。ただし、多くの場合、特に、特定のユーザー行に対して特定のメソッドまたはプロパティを定義する場合には、便利です。また、コードの可読性を向上させることもできます。あなたは、ユーザーの行オブジェクトを取得するときに、完全な名前を取得するために

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

ユーザーテーブルの場合の例ためには、として、カスタムユーザー行にgetFullName()というメソッドを定義することができますユーザーの、あなただけの操作を行います。あなたはユーザーテーブルにいくつかの親テーブルを持っている場合

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

第二の例をは、住所など、です。この場合、ユーザーの行にのgetAddressと呼ばれるメソッドを定義することができます。このシナリオでは

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

次のように、あなたは現在のユーザーのアドレス行オブジェクトを取得します:

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

もう一つの例は、カスタムの削除メソッドまたはinstertメソッドを作成するときに使用します。 delete()メソッドを使用して管理ユーザーを削除しないようにしたいと仮定します。

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

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

この方法では、あなたが管理者ユーザを削除することができないであろうだけで、ユーザーの行オブジェクトのdelete()を呼び出すことによって、次のように続いて、あなたはZend_Db_Table_Rowはからのdeleteメソッドをオーバーロードすることができこれらは、独自の行クラスを定義する有用性を示す3つの基本的な例です。もちろん、それらは必要ではありません。しかし、私自身の経験から、彼らは非常に便利です。

+0

恐ろしい!!!説明のある実生活のサンプルコードをありがとう: - –

+0

+1確かに、非常に良い。 –

+0

質問#373054の答えでは、Userに対してsendMailTo関数があります.Db_Rowクラスにデータベース関連以外の関数を保持するのがよいでしょうか?ユーザー固有のビジネスロジックはどこにあるべきですか? @Hossain Khan。 –

20

一言で言えば、それは分離についてです。

Zend_Db_Tableは、テーブルデータゲートウェイの実装です。 1つのクラスを通して、特定のテーブルビューへのCRUDアクセスを経路指定します。通常はTable Moduleで使用されます。ゲートウェイによって処理されるレコードのビジネスロジックを含むクラス。

Zend_Db_Table_Rowは、Row Data Gateway Patternの実装です。ここで返されるオブジェクトは、データベースレコードとまったく同じように見えますが、そのデータを処理するビジネスロジックが含まれていますが、元のテーブル(ActiveRecord)にCRUDするロジックは含まれていませんが、

object relational impedance mismatchが多すぎない限り、行データゲートウェイは問題ありません。オブジェクトがリレーショナルデータベースでどのように永続化され、どのようにオブジェクト世界でどのように見えるかは、かなり異なる場合があります。 Domain Modelを使用する場合、通常、ビジネスオブジェクトはデータベースに格納されているものとは異なる方法で構造化されます。したがって、データベースから簡単にCRUDすることはできません。これはDataMapperが出場する場所です。

DataMapperは、DomainオブジェクトをRecordsetにマッピングする役割を持ちます。逆もまた同様です。これにより、Domainオブジェクトとデータベース構造が切り離されるため、アプリケーションのメンテナンス性が向上します。それらを分離して保持し、両方のレイヤーを永続化およびドメイン化する方法の柔軟性を向上させます。

関連する問題