/*
这里要说明一下 因为本人比较懒 博客中相关文章的内容更多的是对<深入PHP面向对象、模式与实践>一书中代码的整理和简单注解方便自己日后复习和参考,
对相关内容感兴趣的初学的朋友建议请先阅读原文。此处的内容只能当成一种学习的补充和参考。谢谢!
因原书中领域模型+数据映射器的示例代码是连贯在一起的 所以这里就整理在一起了。
简单介绍一下我的看法,从数据库操作的角度看领域模型主要是操作数据表中的单条记录的而数据映射器是操作整个数据表的数据的。
按原文的解释数据映射器是一个负责将数据库数据映射到对象的类,而领域模型象征着真实世界里项目中的各个参与者,它在数据中通常表现为一条记录。
废话不多说,代码和注解如下:与领域模型相关的三个数据表结构分别为venue(场所)、space(空间)、event(事件)。
create table  'venue' ('id' int(11) not null auto_increment,'name' text,primary key ('id')
)
create table  'space' ('id' int(11) not null auto_increment,'venue' int(11) default null,'name' text,primary key ('id')
)
create table  'event' ('id' int(11) not null auto_increment,'space' int(11) default null,'start' mediumtext,'duration' int(11) default null,'name' text,primary key ('id')
)*///领域模型(这里只建了一个Venue类用于理解)
namespace woo\domain;abstract class DomainObject{            //抽象基类private $id;function __construct ($id=null){$this->id = $id;}function getId(){return $this->id;}//原书没有具体实现,应该是用于获取对象的从属对象的,比如venue(场所)相关的space(空间)对象//具体的代码实现中应该从数据库中查询了相关数据并调用了Collection类,下面看到这个类的时候会有一个了解//而且这个方法的实现应该放在子类中才对static function getCollection($type){      return array();}function collection(){return self::getCollection(get_class($this));}}class Venue extends DomainObject {private $name;private $spaces;function __construct ($id = null,$name=null){$this->name= $name;$this->spaces = self::getCollection('\\woo\\domain\\space'); //这里应该证明了我上述的猜测parent::__construct($id);}function setSpaces(SpaceCollection $spaces){$this->spaces = $spaces;}function addSpace(Space $space){$this->spaces->add($space);$space->setVenue($this);}function setName($name_s){$this->name = $name_s;$this->markDirty();}function getName(){return $this->name;}
}//数据映射器(正如原文的解释数据映射器是一个负责将数据库数据映射到对象的类)
namespace  woo\mapper;abstract class Mapper{            //抽象基类abstract static $PDO;        //操作数据库的pdo对象function __construct (){if(!isset(self::$PDO){$dsn = \woo\base\ApplicationRegistry::getDSN();if(is_null($dsn)){throw new \woo\base\AppException("no dns");}self::$PDO = new \PDO($dsn);self::$PDO->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);}}function createObject($array){                    //将数组创建为上述领域模型中的对象$obj = $this->doCreateObject($array);        //在子类中实现return $obj;}function find($id){                                //通过ID从数据库中获取一条数据并创建为对象$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);return $object;    }function insert(\woo\domain\DomainObject $obj){            //将对象数据插入数据库$this->doInsert($obj);}//需要在子类中实现的各抽象方法abstract function update(\woo\domain\DomainObject $objet);protected abstract function doCreateObject(array $array);protected abstract function selectStmt();protected abstract function doInsert(\woo\domain\DomainObject $object);
}//这里只建立一个VenueMapper类用于理解
class VenueMapper extends Mapper {function __construct (){        parent::__construct();    //各种sql语句对象    $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 \woo\domain\Venue($array['id']);$obj->setname($array['name']);return $obj;}protected function doInsert(\woo\domain\DomainObject $object){  //将对象插入数据库print 'inserting';debug_print_backtrace();$values = array($object->getName());$this->insertStmt->execute($values);$id = self::$PDO->lastInsertId();$object->setId($id);}function update(\woo\domain\DomainObject $object){        //修改数据库数据print "updation\n";$values = array($object->getName(),$object->getId(),$object->getId());$this->updateStmt->execute($values);}function selectStmt(){                    //返回一个sql语句对象return $this->selectStmt;}}/*
Iterator接口定义的方法:
rewind()            指向列表开头
current()            返回当前指针处的元素
key()                返回当前的键(比如,指针的指)
next()
valid()下面这个类是处理多行记录的,传递数据库中取出的原始数据和映射器进去,然后通过数据映射器在获取数据时将其创建成对象*/
abstract class Collection implements \Iterator{protected $mapper;            //数据映射器protected $total = 0;        //集合元素总数量protected $raw = array();    //原始数据private $result;private $pointer = 0;        //指针private $objects = array();    //对象集合function __construct (array $raw = null,Mapper $mapper= null){if(!is_null($raw)&& !is_null($mapper)){$this->raw = $raw;$this->total = count($raw);}$this->mapper = $mapper;}function add(\woo\domain\DmainObject $object){    //这里是直接添加对象$class = $this->targetClass();if(!($object instanceof $class)){throw new Exception("This is a {$class} collection");}$this->notifyAccess();$this->objects[$this->total] = $object;$this->total ++;}abstract function targetClass();    //子类中实现用来在插入对象时检查类型的protected function notifyAccess(){    //不知道干嘛的
        }private function getRow($num){        //获取集合中的单条数据,就是这里通过数据映射器将数据创建成对象$this->notifyAccess();if($num >= $this->total || $num < 0){return null;}if(isset($this->objects[$num]){return $this->objects[$num];}if(isset($this->raw[$num]){$this->objects[$num] = $this->mapper->createObject($this->raw[$num]);return $this->objects[$num];}}public function rewind(){            //重置指针$this->pointer = 0;}public function current(){            //获取当前指针对象return $this->getRow($this->pointer);}public function key(){                //获取当前指针return $this->pointer;}public function next(){            //获取当前指针对象,并将指针下移    $row = $this->getRow($this->pointer);if($row){$this->pointer ++}return $row;}public function valid(){        //验证return (!is_null($this->current()));}}//子类
class VenueColletion extends Collection implements \woo\domain\VenueCollection{function targetClass(){return "\woo\domain\Venue";}
}//客户端
$mapper = new \woo\mapper\VenueMapper();
$venue = $mapper->find(12);
print_r($venue);$venue = new \woo\domain\Venue();
$venue->setName("the likey lounge-yy");
//插入对象到数据库
$mapper->insert($venue);
//从数据库中读出刚才插入的对象
$venue = $mapper->find($venue->getId());
print_r($venue);//修改对象
$venue->setName("the bibble beer likey lounge-yy");
//调用update来更新记录
$mapper->update($venue);
//再次读出对象数据
$venue = $mapper->find($venue->getId());
print_r($venue);//结束

转载于:https://www.cnblogs.com/kerryw/p/7021432.html

PHP面向对象之领域模型+数据映射器相关推荐

  1. 数据源架构模式之数据映射器

    http://lobert.iteye.com/blog/2102312 前面分别介绍了数据源架构模式之表数据入口.数据源架构模式之行和数据入口数据源架构模式之活动记录,相较于这三种数据源架构模式,数 ...

  2. VTK:标记数据映射器用法实战

    VTK:标记数据映射器用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkActor2D.h> ...

  3. vtk类之vtkFixedPointVolumeRayCastMapper :一个固定像素点的体数据映射器

    在vtkImageData中,绘制体数据一种软实现的光线投射算法.算法可以处理所有种类的数据类型,最多四种组件.算法可以采用复合或者MIP渲染方式,并且可以与几何数据混合起来渲染.设置采样间距spac ...

  4. MapStruct系列(5)-映射器数据类型转换详解

    文章目录 前言 1. 隐式类型转换 2. 映射引用类型 3. 嵌套映射 4. 调用自定义映射方法 5. 调用其他映射器 6. 将映射目标类型传递给自定义映射器 7. 将上下文或状态对象传递给自定义方法 ...

  5. 数据校验器架构模式组

    刘 岳林 (yuelin_liu@msn.com), 软件工程师 2007 年 1 月 15 日 本文阐述软件架构与设计模式,它为架构师和开发人员提供了一组关于数据校验的架构模式(隔离校验器,可组装校 ...

  6. Nmap (网络映射器)好东西啊

    2019独角兽企业重金招聘Python工程师标准>>> Nmap  (网络映射器)是由 Gordon Lyon设计,用来探测计算机网络上的主机和服务的一种安全扫描器.为了绘制网络拓扑 ...

  7. 使用FoundationDB高效地将SQL数据映射到NoSQL存储系统中

    NoSQL数据库 --FoundationDB的键-值存储系统 FoundationDB是一个分布式的键-值存储系统,支持全局ACID事务操作,并且性能出众.在安装系统时,可以指定数据分发的级别.数据 ...

  8. SpringMVC - 非注解的处理器映射器和适配器

    为什么80%的码农都做不了架构师?>>>    一.非注解的处理器映射器 提供的处理器有两个属性.一个是id属性,一个是name属性.分别对应两种不同的映射器. <bean i ...

  9. mybatis的mapper.xml文件中含有中文注释时运行出错,mybatis配置优化和别名优化 mybatis配置之映射器说明

    记录一个发现的小问题,刚刚在UserMapper.xml文件中有一段中文注释掉的内容: <!-- <resultMap id="Usermap" type=" ...

  10. 非注解和注解的处理器映射器和适配器---SpringMVC学习笔记(三)

    非注解的处理器映射器和适配器 非注解的处理器映射器 之前的入门Demo中使用的就是非注解的处理器映射器: org.springframework.web.servlet.handler.BeanNam ...

最新文章

  1. mysql 设置 0、1 用什么数据类型_MySQL索引的基本使用
  2. Win10年度更新开发必备:VS2015 Update 3正式版下载汇总
  3. word 2010中如何创建多级目录和多级列表
  4. ALV标准范例Demo汇总
  5. C语言学习之求两个整数的最大值
  6. mysql-nt.exe w3wp.exe cpu 100%_认识w3wp.exe进程,从根本上解决占用资源较大问题
  7. 一段简单的html 5 音频,5个用于处理HTML5音频的库和API
  8. 信奥中的数学:计算几何
  9. BZOJ.1029.[JSOI2007]建筑抢修(贪心)
  10. 微软语音 AI 技术与微软听听文档小程序实践 | AI ProCon 2019
  11. codeforce 604B More Cowbell
  12. 最常使用Eclipse快捷键
  13. 2021/9/7 ad9361 SPI 通信与数据接口
  14. qrc文件编译到可执行文件exe
  15. CodeForces - 884B Japanese Crosswords Strike Back
  16. Fatal error: init(coder:) has not been implemented in Swfit
  17. 1-Unity是什么
  18. 2021年的Gartner云基础设施和平台服务魔力象限有什么不一样?
  19. OSChina 周六乱弹 —— 网恋有风险面基需谨慎
  20. 腾讯云服务器外网访问

热门文章

  1. linux简单进程调用
  2. web.config点滴:更改login控件对密码安全性的要求
  3. compose yaml规则
  4. 改变elementui卡片crad样式_elementUI步骤条样式改造
  5. windows 64位sed.exe_32位,64位,x86,x64到底是什么关系?差距居然这么大
  6. emply() php,thinkphp3.2.3 分页代码分享
  7. 大数据学情分析_大数据时代|如何轻松做好学情分析
  8. EChart:EChart与NProgress结合异步加载数据
  9. jQuery特效:实现抽奖
  10. Javascript特效:简易留言板