假设我有两个对象,类别和产品:
类别
<?php class Category {
private $name;
public function __construct(string $name) {
$this->name = $name;
}
}
?>
产品
<?php class Product {
private $name, $category;
public function __construct(string $name, Category $category) {
$this->name = $name;
$this->category = $category;
}
}
?>
我有一个CategoryMapper,它从数据库中获取(和插入/更新/删除)Category对象:
分类管理员
<?php
class CategoryMapper {
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function ofId($id) : ?Category {
$query = 'SELECT name FROM category WHERE id = ?';
$stmt = $pdo->prepare($query);
$stmt->execute([$id]);
if ($row = $stmt->fetch()) {
return new Category($row['name']);
}
return null;
}
// Other methods
}
?>
我还需要一个ProductMapper,但是ProductMapper的
ofId()
方法需要返回一个包含Category对象的产品对象。
现在我的问题是:我的ProductMapper应该如何构造?
选项1-在构造函数中传递ProductMapper一个CategoryMapper
如果CategoryMapper需要另一个Mapper,而Mapper又需要另一个Mapper,等等,我想这可能会变得很大。
<?php
class ProductMapper {
private $pdo, $categoryMapper;
public function __construct(PDO $pdo, CategoryMapper $categoryMapper) {
$this->pdo = $pdo;
$this->categoryMapper = $categoryMapper;
}
public function ofId($id) {
$query = 'SELECT name, categoryId FROM product WHERE id = ?';
$stmt = $pdo->prepare($query);
$stmt->execute([$id]);
if ($row = $stmt->fetch()) {
$category = $this->categoryMapper->ofId($row['categoryId']);
return new Product($row['name'], $category);
}
return null;
}
}
?>
选项2-让ProductMapper在需要的方法中创建CategoryMapper
如果ProductMapper需要很多其他的映射器,我可能会在这里忽略ProductMapper实际使用的映射器,因为它们不是在一个地方列出的,而是分散在整个代码中。
<?php
class ProductMapper {
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function ofId($id) {
$query = 'SELECT name, categoryId FROM product WHERE id = ?';
$stmt = $pdo->prepare($query);
$stmt->execute([$id]);
if ($row = $stmt->fetch()) {
$categoryMapper = new CategoryMapper($this->pdo);
$category = $categoryMapper->ofId($row['categoryId']);
return new Product($row['name'], $category);
}
return null;
}
}
?>
选项3-不要使用CategoryMapper并在ProductMapper中复制build-a-category代码
这只会导致大量重复的代码(特别是当嵌入的对象变大或对象也嵌入其中时)。
<?php
class ProductMapper {
private $pdo;
public function __construct(PDO $pdo) {
$this->pdo = $pdo;
}
public function ofId($id) {
$query = 'SELECT p.name as productName, c.name as categoryName FROM product p join category c on p.categoryId = c.id WHERE p.id = ?';
$stmt = $pdo->prepare($query);
$stmt->execute([$id]);
if ($row = $stmt->fetch()) {
$category = new Category($row['categoryName']);
return new Product($row['productName'], $category);
}
return null;
}
}
?>
那么这通常是怎么做的呢?
还有其他我没想到的选择吗?