副问题[/!--empirenews.page--]
事变单位
这个模式涉及到了规模模子、数据映射器和标识映射,这里就同一举办清算和回首了。
$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{
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|