侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP面向对象之领域模型+数据映射器实例(分析)

php  /  管理员 发布于 7年前   325

这里要说明一下 因为本人比较懒 博客中相关文章的内容更多的是对<深入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);//结束

以上这篇PHP面向对象之领域模型+数据映射器实例(分析)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

您可能感兴趣的文章:

  • 详解PHP的Laravel框架中Eloquent对象关系映射使用
  • ThinkPHP中公共函数路径和配置项路径的映射分析
  • 回答PHPCHINA上的几个问题:URL映射
  • 解密ThinkPHP3.1.2版本之模块和操作映射
  • PHP实现路由映射到指定控制器
  • 浅析php设计模式之数据对象映射模式
  • 老生常谈PHP面向对象之标识映射
  • PHP实现的数据对象映射模式详解
  • PHP数据对象映射模式实例分析
  • php实现映射操作实例详解


  • 上一条:
    php基于SQLite实现的分页功能示例
    下一条:
    PHP基于PDO实现的SQLite操作类【包含增删改查及事务等操作】
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客