I’m working on creating a domain layer in Zend Framework that is separate from the data access layer. The Data Access Layer is composed to two main objects, a Table Data Gateway and a Row Data Gateway. As per Bill Karwin’s reply to this earlier question I now have the following code for my domain Person object:
class Model_Row_Person { protected $_gateway; public function __construct(Zend_Db_Table_Row $gateway) { $this->_gateway = $gateway; } public function login($userName, $password) { } public function setPassword($password) { } }
However, this only works with an individual row. I also need to create a domain object that can represent the entire table and (presumably) can be used to iterate through all of the Person’s in the table and return the appropriate type of person (admin, buyer, etc) object for use. Basically, I envision something like the following:
class Model_Table_Person implements SeekableIterator, Countable, ArrayAccess { protected $_gateway; public function __construct(Model_DbTable_Person $gateway) { $this->_gateway = $gateway; } public function current() { $current = $this->_gateway->fetchRow($this->_pointer); return $this->_getUser($current); } private function _getUser(Zend_Db_Table_Row $current) { switch($current->userType) { case 'admin': return new Model_Row_Administrator($current); break; case 'associate': return new Model_Row_Associate($current); break; } } }
Is this is good/bad way to handle this particular problem? What improvements or adjustments should I make to the overall design?
Thanks in advance for your comments and criticisms.
I had in mind that you would use the Domain Model class to completely hide the fact that you’re using a database table for persistence. So passing a Table object or a Row object should be completely under the covers:
I don’t buy into any blanket statement that
staticis always bad, or singletons are always bad, orgotois always bad, or what have you. People who make such unequivocal statements are looking to oversimplify the issues. Use the language tools appropriately and they’ll be good to you.That said, there’s often a tradeoff when you choose one language construct, it makes it easier to do some things while it’s harder to do other things. People often point to
staticmaking it difficult to write unit test code, and also PHP has some annoying deficiencies related to static and subclassing. But there are also advantages, as we see in this code. You have to judge for yourself whether the advantages outweigh the disadvantages, on a case by case basis.I don’t think that’s necessary.
I named the method
get()just to be distinct fromfind(). The ‘getter’ paradigm is associated with OO interfaces, while ‘finders’ are traditionally associated with database stuff. We’re trying to design the Domain Model to pretend there’s no database involved.I’d resist creating a generic
getBy()method, because it’s tempting to make it accept a generic SQL expression, and then pass it on to the data access objects verbatim. This couples the usage of our Domain Model to the underlying database representation.