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:

  • The controller can create the new Organisation object and use a mapper, 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.
  • The controller can create the new Organisation object, and this object does the rest of the work itself. It would call 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

    上一篇: 如何(以及在​​哪里)构建一个具有大量参数的实体?

    下一篇: 这应该是控制器还是域的责任?