通过数据映射器处理集合模式中的项目

时间:2013-06-17 10:54:22

标签: php design-patterns collections architecture datamapper

我的问题与@tereško's中的Who should handle the conditions in complex queries, the data mapper or the service layer?回答的更新部分有关。以下是供参考和使用的代码。

$category = new Category;
$category->setTitle( 'privacy' );

$list = new ArticleCollection;

$list->setCondition( $category );
$list->setDateRange( mktime( 0, 0, 0, 12, 9, 2001) );
// it would make sense, if unset second value for range of dates 
// would default to NOW() in mapper

$mapper = new ArticleCollectionMapper;
$mapper->fetch( $list );

foreach ( $list as $article )
{
    $article->setFlag( Article::STATUS_REMOVED );
}

$mapper->store( $list );

在此代码中,ArticleCollection是域对象的集合,我们称之为ArticleArticleCollectionMapper从数据库中提取数据并将其分配给$list的那一刻,需要Article的实例(对于每一行)。是Article的实例是否会通过类似$list的方法添加到我们的集合实例($list->addArticle($newArticle))中,如果使用像ArticleFactory这样的工厂对象,或者是我还没有考虑过另一种选择?

1 个答案:

答案 0 :(得分:2)

我不认为实际使用工厂对象来添加文章。但是,您可能会看到自己使用一个来创建Article的实例(在第二个示例中)。我前进和做的是向addArticles ()实例添加ArticleCollection方法。这样,您只需从映射器中调用ArticleCollection实例上的方法即可。 ArticleCollectionMapper可能类似于:

class ArticleCollectionMapper extends DataMapperAbstract
{
    public function fetch ( ArticleCollection $articles )
    {
        $prepare = $this->connection->prepare( "SELECT ..." );
        $prepare->execute();
        // filter conditions

        $articles->addArticles( $prepare->fetchAll() );
    }
}

您需要通过从ArticleCollection实例获取条件来进行一些过滤,该条件从上面的代码段中排除。然后我们的域对象的addArticles()实现看起来类似于:

class ArticleCollection extends DomainObjectAbstract
{
    protected $collection = array();

    public function addArticles ( Array $articles )
    {
        foreach ( $articles as $article )
        {
            $articleCollectionItem = new Article;
            $articleCollectionItem->setParams( $article );
            // however you prefer filling your list with `Article` instances

            $this->collection[] = $articleCollectionItem;
        }
    }
}

您可能还想根据自己的需要添加addArticle()方法,然后通过调用foreach替换上面addArticle()内的内容。请注意,上述示例极为简化, 代码需要进行调整才能达到您的标准。