| 
                         工作单元 
这个模式涉及到了领域模型、数据映射器和标识映射,这里就统一进行整理和回顾了。 
$venue = new woodomainVenue(null,"The Green Tree");
 
woodomainObjectWatcher::instance()->performOperations(); 
现在以上面的二行客户端代码为切入点大概的叙述一下这个模式是怎么工作的。 
第一句在使用领域模型对象创建一个对象的时候,它就调用了标识映射ObjectWatcher类 
将自己标记为一个需要新增的对象。第二句的performOperations方法将保存在标识映射器的属性$new中的对象 
插入到了数据库中。注意它内部调用的$obj->finder()方法是领域模式中通过HelperFactory工厂类生成一个相对应的数据映射器类并return过来。 
HelperFactory这个类下面没有具体实现(原文也没有实现),其实就是根据参数传入的类的类型使用条件分支创建对应的数据映射器。 
下面直接看代码和注释进行理解。
 
//标识映射 
class ObjectWatcher{
private $all = array();        //存放对象的小仓库 
private $dirty = array();      //存放需要在数据库中修改的对象 
private $new = array();        //存放需要在数据库中新增的对象 
private $delete = array();      //存放需要在数据库中删除的对象 
private static $instance;      //单例 
private function __construct (){} 
static function instance(){ 
if(!self::$instance){ 
self::$instance = new ObjectWatcher(); 
} 
return self::$instance; 
} 
//获取一个唯一的标识,这里采用了领域类类名+ID的方式创建一个唯一标识,避免多个数据库表调用这个类时出现ID重复的问题 
function globalKey(DomainObject $obj){ 
$key = get_class($obj) . "." . $obj->getId(); 
return $key; 
} 
//添加对象 
static function add(DomainObject $obj){ 
$inst = self::instance(); 
$inst->all[$inst->globalKey($obj)] = $obj; 
} 
//获取对象 
static function exists($classname,$id){ 
$inst = self::instance(); 
$key = "$classname.$id"; 
if(isset($inst->all[$key]){ 
return $inst->all[$key]; 
} 
return null; 
} 
//标记为需要删除的对象 
static function addDelete(DomainObject $obj){ 
$self = self::instance(); 
$self->delete[$self->globalKey($obj)] = $obj; 
} 
//标记为需要修改的对象 
static function addDirty(DomainObject $obj){ 
$inst = self::instance(); 
if(!in_array($obj,$inst->new,true)){ 
$inst->dirty[$inst->globalKey($obj)] = $obj; 
} 
} 
//标记为需要新增的对象 
static function addNew(DomainObject $obj){ 
$inst = self::instance(); 
$inst->new[] = $obj; 
} 
//标记为干净的对象 
static function addClean(DomainObject $obj){ 
$self = self::instance(); 
unset($self->delete[$self->globalKey($obj)]); 
unset($self->dirty[$self->globalKey($obj)]); 
$self->new = array_filter($self->new,function($a) use($obj) {return !($a === $obj);}); 
} 
//将上述需要增删改的对象与数据库交互进行处理 
function performOperations(){ 
foreach($this->dirty as $key=>$obj){ 
$obj->finder()->update($obj);    //$obj->finder()获取一个数据映射器 
} 
foreach($this->new as $key=>$obj){ 
$obj->finder()->insert($obj); 
} 
$this->dirty = array(); 
$this->new = array(); 
} 
} 
//领域模型 
abstract class DomainObject{      //抽象基类 
private $id = -1; 
function __construct ($id=null){ 
if(is_null($id)){ 
$this->markNew();      //初始化时即被标记为需要新增的对象了 
} else { 
$this->id = $id; 
} 
} 
//调用了标识映射的标记对象的方法 
function markNew(){ 
ObjectWatcher::addNew($this); 
} 
function markDeleted(){ 
ObjectWatcher::addDelete($this); 
} 
function markDirty(){ 
ObjectWatcher::addDirty($this); 
} 
function markClean(){ 
ObjectWatcher::addClean($this); 
} 
function setId($id){ 
$this->id = $id; 
} 
function getId(){ 
return $this->id; 
} 
function finder(){ 
return self::getFinder(get_class($this)); 
} 
//通过工厂类来实例化一个特定类型的数据映射器对象,例如VenueMapper 
//这个对象将被标识映射器中的performOperations方法调用用于与数据库交互进行增删改的操作 
static function getFinder($type){ 
return HelperFactory::getFinder($type); 
} 
} 
class Venue extends DomainObject { 
private $name; 
private $spaces; 
function construct ($id = null,$name=null){ 
$this->name= $name; 
$this->spaces = self::getCollection('woodomainspace'); 
parent::construct($id); 
} 
function setSpaces(SpaceCollection $spaces){ 
$this->spaces = $spaces; 
$this->markDirty();            //标记为需要修改的对象 
} 
function addSpace(Space $space){ 
$this->spaces->add($space); 
$space->setVenue($this); 
$this->markDirty();            //标记为需要修改的对象 
} 
function setName($name_s){ 
$this->name = $name_s; 
$this->markDirty();            //标记为需要修改的对象 
} 
function getName(){ 
return $this->name; 
} 
} 
//领域模型 
class Space extends DomainObject{ 
//......... 
function setName($name_s){ 
$this->name = $name_s; 
$this->markDirty(); 
} 
function setVenue(Venue $venue){ 
$this->venue = $venue; 
$this->markDirty(); 
} 
} 
//数据映射器 
abstract class Mapper{ 
abstract static $PDO;    //操作数据库的pdo对象 
function __construct (){ 
if(!isset(self::$PDO){ 
$dsn = woobaseApplicationRegistry::getDSN(); 
if(is_null($dsn)){ 
throw new woobaseAppException("no dns"); 
} 
self::$PDO = new PDO($dsn); 
self::$PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 
} 
} 
//获取标记的对象 
private function getFroMap($id){ 
return woodomainObjectWatcher::exists($this->targetClass(),$id); 
} 
//新增标记的对象 
private function addToMap(woodomainDomainObject $obj){////// 
return woodomainObjectWatcher::add($obj); 
} 
//将数据库数据映射为对象 
function createObject($array){ 
$old = $this->getFromMap($array['id']); 
if($old){return $old;} 
$obj = $this->doCreateObject($array); 
$this->addToMap($obj); 
$obj->markClean(); 
return $obj; 
} 
function find($id){                //通过ID从数据库中获取一条数据并创建为对象 
$old = $this->getFromMap($id); 
if($old){return $old}             
$this->selectStmt()->execute(array($id));
$array= $this->selectStmt()->fetch();
$this->selectStmt()->closeCursor();
if(!is_array($array)){
  return null;
}
if(!isset($array['id'])){
  return null;
}
$object = $this->createObject($array);
$this->addToMap($object);          
return $object;   
} 
function insert(woodomainDomainObject $obj){      //将对象数据插入数据库 
$this->doInsert($obj); 
$this->addToMap($obj); 
} 
//需要在子类中实现的各个抽象方法 
abstract function targetClass();                    //获取类的类型 
abstract function update(woodomainDomainObject $objet);        //修改操作 
protected abstract function doCreateObject(array $array);        //创建对象 
protected abstract function selectStmt();                //查询操作 
protected abstract function doInsert(woodomainDomainObject $object);  //插入操作 
} 
class VenueMapper extends Mapper { 
function construct (){ 
parent::construct(); 
//预处理对象 
$this->selectStmt = self::$PDO->prepare("select * from venue where id=?"); 
$this->updateStmt = self::$PDO->prepare("update venue set name=?,id=? where id=?"); 
$this->insertStmt = self::$PDO->prepare("insert into venue (name) values(?)"); 
} 
protected function getCollection(array $raw){    //将Space数组转换成对象集合 
return new SpaceCollection($raw,$this); 
} 
protected function doCreateObject (array $array){  //创建对象 
$obj = new woodomainVenue($array['id']); 
$obj->setname($array['name']); 
return $obj; 
} 
protected function doInsert(woodomainDomainObject $object){ //将对象插入数据库 
print 'inserting'; 
debug_print_backtrace(); 
$values = array($object->getName()); 
$this->insertStmt->execute($values); 
$id = self::$PDO->lastInsertId(); 
$object->setId($id); 
} 
                        (编辑:莱芜站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |