0

0

PHP面向对象之关于领域模型和数据映射器的示例代码分享

黄舟

黄舟

发布时间:2017-06-18 13:38:52

|

1342人浏览过

|

来源于php中文网

原创

Tanka
Tanka

具备AI长期记忆的下一代团队协作沟通工具

下载

php面向对象之关于领域模型和数据映射器的示例代码分享

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

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  woomapper;

abstract class Mapper{            //抽象基类
    abstract static $PDO;        //操作数据库的pdo对象
    function construct (){
        if(!isset(self::$PDO){
            $dsn = wooaseApplicationRegistry::getDSN();
            if(is_null($dsn)){
                throw new wooaseAppException("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(woodomainDomainObject $obj){            //将对象数据插入数据库
        $this->doInsert($obj);
    }
    
    //需要在子类中实现的各抽象方法
    abstract function update(woodomainDomainObject $objet);
    protected abstract function doCreateObject(array $array);
    protected abstract function selectStmt();
    protected abstract function doInsert(woodomainDomainObject $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 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);
    }
    
    function update(woodomainDomainObject $object){        //修改数据库数据
        print "updation
";
        $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(woodomainDmainObject $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 woodomainVenueCollection{
    function targetClass(){
        return "woodomainVenue";
    }
}


//客户端
$mapper = new woomapperVenueMapper();
$venue = $mapper->find(12);
print_r($venue);

$venue = new woodomainVenue();
$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速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

php

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

705

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

233

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

117

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

22

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

61

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

30

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

669

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

58

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 12.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.2万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号