Should this be the responsibility of the controller or the domain?
In my application I have Users, Organisations and Employees. There are domain objects for each of these, and database mappers.
When a User initially sets up an Organisation, I want to automatically create an Employee record for that User/Organisation combination. (The type of record will be Owner). Basically this comes down to two database inserts: one for Organisation, the other for Employee.
I can see two ways to go about this:
orgMapper::insert($newOrg)
, to persist it. With that done it can then create the new Employee object and again use a mapper, employeeMapper::insert($newOwner)
, for persistence. orgMapper::insert($this)
, and with the key which is returned would then create and persist the new Employee object. There seems to be a number of benefits in the second approach: the business logic (ie an employee/Owner record for each new Organisation) is embedded in the model, and the controller is skinnier. The only reason I hesitate is that this means my domain is becoming dependent on my mapper.
I would use a factory in the domain to get the mapper, so all coupling would come down to a single point. Does this make the dependency acceptable? Or do I have a deeper design issue?
I have read a bit about a service layer. Perhaps this is where I should be looking?
I am using PHP and Zend Framework
Your thoughts are much appreciated. My cat and I have exhausted our own ideas...
Since I am not a ZF user (and have been avoiding it), maybe my solution would not apply.
Data mappers are not supposed to work with just a single table in database. Instead, when you are storing the new Organization
entry (and i guess the Organization
instance contains a collection of Employee
objects), the mapper also should create all the entries for the Employees, and the accompanying data in OrganizationEmpoyees
table.
The short answer: neither, storage is responsibility of mapper.
If I misunderstood the DB structure, and how it relates to "(..) Employee record for that User/Organisation combination" and the the Employee
domain objects are completely separate from Organization
, then the 1st of your solutions would be acceptable.
As for adding service on top of domain objects and mappers, that would be a good idea. Because you have been leaking domain logic inside the controller already. Seems like a bad thing to do.
I can tell you what I do in cases like this. Anytime I need to take a pile of data and build more then one object from it, I dump the whole mess to another model (maybe a service layer, I don't know) and sort out the objects away from the controller. I just use controllers to grab data and send it somewhere else (view or model).
For example I want to save some data from my music collection, the data is currently in a csv file. My controller parses the csv file and puts each line of data into an array which I forward to a class method that sorts the data into objects and saves it to the database. (Plz note this method is preliminary and requires some tweaking and adjustment)
//FROM class Application_Model_Tag
public function saveTags() {
//TODO implement instantiation of Domain Models instead of passing arrays to mappers
$trackMapper = new Music_Model_Mapper_Track();
$artistMapper = new Music_Model_Mapper_Artist();
$albumMapper = new Music_Model_Mapper_Album();
if (isset($this->_hash)) {
//see if track already exists by comparing hashs
$trackRow = $trackMapper->fetchByColumn('hash', $this->getHash());
//if track does not exist
if (is_null($trackRow)) {
//save the artist
$artistData = array(
'name' => $this->getArtist()
);
//see it the artist exists by name
$artistRow = $artistMapper->fetchByColumn('name', $this->getArtist());
//does artist exist?
if (is_null($artistRow)) {
$artistRow = $artistMapper->save($artistData);
}
//Save the Album Data
//does the album exist?
$albumRow = $albumMapper->fetchByColumn('name', $this->getAlbum());
//if yes
if (is_null($albumRow)) {
$albumData = array(
'name' => $this->getAlbum(),
'artist_id' => $artistRow->id,
'art' => $this->getAlbum() . '.jpg',
'year' => $this->getYear()
);
//get album row
$albumRow = $albumMapper->save($albumData);
}
//Save track data
$trackData = array(
'title' => $this->getTitle(),
'filename' => $this->getFilename(),
'path' => $this->getPath(),
'format' => $this->getFormat(),
'genre' => $this->getGenre(),
'artist_id' => $artistRow->id,
'album_id' => $albumRow->id,
'track' => $this->getTrack(),
'play_time' => $this->getPlay_time(),
'hash' => $this->getHash()
);
//save track data
$trackMapper->save($trackData);
}
} else {
return;
}
}
I hope this helps, and please forgive the crudity of the example.
链接地址: http://www.djcxy.com/p/61454.html上一篇: 如何(以及在哪里)构建一个具有大量参数的实体?
下一篇: 这应该是控制器还是域的责任?