1

在我的应用程序中,我有用户、组织和员工。每个都有域对象和数据库映射器。

当用户最初设置组织时,我想为该用户/组织组合自动创建员工记录。(记录类型将是所有者)。基本上这归结为两个数据库插入:一个用于组织,另一个用于员工。

我可以看到两种方法来解决这个问题:

  1. 控制器可以创建新的组织对象并使用映射器orgMapper::insert($newOrg)来持久化它。完成后,它可以创建新的 Employee 对象并再次使用映射器employeeMapper::insert($newOwner), 来进行持久化。
  2. 控制器可以创建新的组织对象,这个对象自己完成其余的工作。它会调用orgMapper::insert($this),然后使用返回的键创建并保存新的 Employee 对象。

第二种方法似乎有很多好处:业务逻辑(即每个新组织的员工/所有者记录)嵌入到模型中,并且控制器更精简。我犹豫的唯一原因是这意味着我的域变得依赖于我的映射器。

我会使用域中的工厂来获取映射器,因此所有耦合都会归结为一个点。这是否使依赖性可以接受?还是我有更深层次的设计问题?

我已经阅读了一些关于服务层的信息。也许这就是我应该寻找的地方?

我正在使用 PHP 和 Zend 框架

非常感谢您的想法。我和我的猫已经用尽了我们自己的想法......

4

2 回答 2

2

由于我不是 ZF 用户(并且一直在避免使用它),所以我的解决方案可能不适用。

数据映射器不应该只使用数据库中的单个表。相反,当您存储新Organization条目时(我猜该Organization实例包含Employee对象集合),映射器还应该为员工创建所有条目,以及OrganizationEmpoyees表中的随附数据。

简短的回答:两者都不是,存储是映射器的责任。

如果我误解了数据库结构,以及它与“(..)该用户/组织组合的员工记录”的关系,并且Employee域对象与 完全分开Organization,那么您的第一个解决方案将是可以接受的。


至于在域对象和映射器之上添加服务,那将是一个好主意。因为您已经在控制器内部泄漏域逻辑。似乎是一件坏事。

于 2012-06-09T10:54:25.453 回答
0

我可以告诉你在这种情况下我会怎么做。每当我需要获取一堆数据并从中构建多个对象时,我会将整个混乱转储到另一个模型(可能是服务层,我不知道)并从控制器中整理出对象。我只是使用控制器来获取数据并将其发送到其他地方(视图或模型)。

例如,我想从我的音乐收藏中保存一些数据,这些数据当前位于 csv 文件中。我的控制器解析 csv 文件并将每一行数据放入一个数组中,我将其转发给一个类方法,该方法将数据分类为对象并将其保存到数据库中。(请注意这种方法是初步的,需要一些调整和调整)

//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;
        }
    }

我希望这会有所帮助,请原谅这个例子的粗鲁。

于 2012-06-09T12:24:48.890 回答