好的,我有问题。我一直在使用一种datamapper方法来加载我的对象。我对这种方法(以及一般的OO)都很陌生,所以问题不时出现。到目前为止,我的场景相对简单。例如,我有一个包含产品的数据库表。产品具有名称,代码,描述,产品组(实际上是对另一个表的引用)等字段。使用ProductMapper加载和初始化产品类,ProductMapper查询产品和产品组表并返回对象。
Class Product
{
private $id;
private $code;
...
public function __construct($id){
$this->id = $id;
}
public function getName(){
return $this->name;
}
...
}
Class ProductMapper
{
private $db;
public function __construct (PDO $db){
$this->db = $db;
}
public function find($id){
$sql = $this->db->prepare("SELECT p.ID, p.Name, p.Code, p.Price, p.Description, p.ProductGroup, p.ProductGroupName, p.PackageSize
FROM products p
INNER JOIN productgroups g ON p.ProductGroupID = g.ID
WHERE p.ID = :id");
$sql->bindValue(':id',$id, PDO::PARAM_INT);
$sql->execute();
$productResult = $sql->fetchAll(PDO::FETCH_ASSOC);
if(count($productResult) == 1){
$product = new Product($id);
$product->setName($result[0]['Name']);
...
return $product;
}
}
}
到目前为止,一切都适合我。我使用这种方法的问题是,如果我想(并且我真的想要)为ProductGroup创建一个类和一个映射器。我的计划是将Product类中的ProductGroupID替换为实际的ProductGroup对象。
我想出了几个可以实现这一目标的方案:
1:在ProductMapper类中创建ProductGroupMapper:
Class ProductMapper
{
private $db;
private $groupMapper;
public function __construct (PDO $db){
$this->db = $db;
$this->groupMapper = new ProductGroupMapper($db);
}
...
}
2:将产品和产品组创建为单独的对象:
$product = $productMapper->find(1);
$group = $productGroupMapper->find($product->getGroupID());
$product->setGroup($group);
3:将ProductGroup映射器作为ProductMapper的依赖项传递:
Class ProductMapper
{
private $db;
private $groupMapper;
public function __construct (PDO $db, ProductGroupMapper $pgMapper){
$this->db = $db;
$this->groupMapper = $pgMapper;
}
...
}
第一个选项在两个映射器之间创建了一个非常紧密的耦合,这让我感到非常紧张。第二个选项可能更灵活,但会产生大量额外代码并且容易出错。我最喜欢第三种选择,但我仍然担心我可能会把自己画成一个角落......至于创建地图选手,我正在考虑创建一些工厂类,它会创建正确的映射器并注入必要的依赖性
或者我只是弄得一团糟?