我对Data Mapper 模式很陌生。我想我错过了一些东西,因为对我来说,它对于比最基本的例子更复杂的所有事情都失败了。
假设我有一个由页面组成的简单网站:
class Page {
private $id = null;
private $parent = null;
private $title = null;
private $body = null;
public function setId($id) { $this->id = (int) $id; }
public function setParent(Page $parent) { $this->parent = $parent; }
public function setTitle($title) { $this->title = $title; }
public function setBody($body) { $this->body = $body; }
public function getId() { return $this->id; }
public function getParent() { return $this->parent; }
public function getTitle() { return $this->title; }
public function getBody() { return $this->body; }
}
现在我想实例化树深处的第 7 页:
- 第 1 页
- 第2页
- 第 3 页
- 第 4 页
- 第 5 页
- 第 6 页
- 第 7 页
- 第 6 页
- 第 5 页
- 第 4 页
- 第 3 页
- 第2页
class PageMapper {
public function fetch($id) {
//...
$data = $db->fetchRow("SELECT * FROM `pages` WHERE `id` = ?", $id);
$page = new Page();
$page->setId($data['id']);
$page->setTitle($data['title']);
$page->setBody($data['body']);
if ($data['parent_id'] !== null) {
$page->setParent(
$this->fetch($data['parent_id']);
);
}
}
public function save(Page $page) {
//...
}
}
问题很明显:我必须一直实例化所有父页面,直到根页面。
现在想象一个 Page 需要知道它的子节点。这意味着,如果我想实例化根 Page,我将不得不加载整个 tree。
一种解决方案可能是仅按需加载父/子,但这意味着域对象必须了解映射器才能从中提取数据......并且分离将消失。
域模型(Page类的实例)应该对 Data Mapper 层(分离)一无所知,但仍然能够执行这些任务(检索父/子)。
在这些情况下是否可以实现关注点分离?如果是,如何?