0

0

php中选择工厂和更新工厂模式介绍

零下一度

零下一度

发布时间:2017-06-30 15:59:51

|

1368人浏览过

|

来源于php中文网

原创

/*选择工厂和更新工厂模式,这个模式的类(UpdateFactory和SelectionFactory类)就是用来创建SQL语句的.
因为涉及到之前学习的内容比较多,这里就尽量将之前相关模式的示例代码放在一起来进行学习和回顾了。
以下的代码都是代码片段而且涉及到连接数据库,无法进行整体的调试(某些部分单独拿出来的话就可以),因此重在理解。*///更新工厂abstract class UpdateFactory{    abstract function newUpdate(woodomainDomainObject $obj);    //拼接更新或插入的sql语句protected function buildStatement($table,array $fields ,array $condition = null){$terms = array(); //SQL语句中占位符所代表的实际值if(!is_null($condition)){        //有条件则拼接更新语句,无条件则拼接插入语句$query = "UPDATE {$table} SET";$query .= implode(" = ? " ,array_keys($fields)) . " = ? ";$terms = array_values($fields);$cond = array();$query .= " WHERE ";foreach($condition as $key=>$val){$cond[] = " $key = ? ";$terms[] = $val;
            }$query .= implode(" AND ",$cond);
        } else {$query = " INSERT INTO {$table} (";$query .= implode(",",array_keys($fields));$query .= " ) VALUES ( ";foreach($fields as $name => $value){$terms[] = $value;$qs[] = "?";
            }$query .= implode(",",$qs);$query .=" ) ";
        }return array($query,$terms);
    }
}//通过领域模型生成SQL语句class VenueUpdateFactory extends UpdateFactory{function newUpdate(woodomainDomainObject $obj){$id = $obj->getId();$cond = null;$values['name'] = $obj->getName();if($id > -1 ){$cond["id"] = $id;
        }return $this->buildStatement("venue",$values,$cond);
    }
}//选择工厂abstract class SelectionFactory{abstract function newSelection(IdentityObject $obj);    //通过标识对象拼接sql语句的where条件语句function buildWhere (IdentityObject $obj){if($obj->isVoid){return array("",array());
        }$compstrings = array();$values = array();foreach($obj->getComps() as $comp){$compstrings[] = "{$comp['name']} {$comp['operator']} ?";$values[] = $comp['value'];
        }$where =  " WHERE " . implode(" AND ",$compstrings);return array($where,$values);
    }
}//拼接select语句class VenuSelectionFactory extends SelectionFactory {function newSelection(IdentityObject $obj){$field = implode(',',$obj->getObjectFields());$core = "SELECT $fields FROM venue";list($where,$values) = $this->buildWhere($obj);return array($core." ".$where,$values);
    }
}

//现在来回顾一下之前学习过的相关知识//字段对象class Field {protected $name = null;          //字段名称protected $operator = null;         //操作符    protected $comps = array();         //存放条件的数组    protected $incomplete = false;     //检查条件数组是否有值function __construct ($name){$this->name= $name;
    }    //添加where 条件function addTest($operator,$value){$this->comps[] = array('name'=>$this->name,'operator'=>$operator,'value'=>$value);
    }    //获取存放条件的数组function getComps(){return $this->comps;
    }    function isIncomplete(){return empty($this->comps);
    }
}//标识对象,主要功能就是拼接where条件语句class IdentityObject {protected $currentfield = null;        //当前操作的字段对象protected $fields = array();        //字段对象集合private $and = null;private $enforce = array();            //限定的合法字段        function __construct($field = null, array $enforce = null){if(!is_null($enforce)){$this->enforce = $enforce;
        }if(!is_null($field)){$this->field($field);
        }
    }    //获取限定的合法字段function getObjectFields(){return $this->enforce;
    }    //主要功能为设置当前需要操作的字段对象function field($fieldname){if(!$this->isVoid()&& $this->currentfield->isIncomplete()){throw new Exception("Incomplete field");
        }$this->enforceField($fieldname);if(isset($this->fields[$fieldname]){$this->currentfield = $this->fields[$fieldname];
        } else {$this->currentfield = new Field($fieldname);$this->fields[$fieldname] = $this->currentfield;
        }return $this;                    //采用连贯语法    }    //字段集合是否为空function isVoid(){return empty($this->fields);
    }    //检查字段是否合法function enforceField ($fieldname){if(!in_array($fieldname,$this->enforce) && !empty($this->enforce)){$forcelist = implode(',',$this->enforce);throw new Exception("{$fieldname} not a legal field {$forcelist}");
        }
    }    
    //向字段对象添加where条件function eq($value){return $this->operator("=",$value);
    }    function lt($value){return $this->operator("<",$value);
    }    function gt($value){return $this->operator(">",$value);
    }    //向字段对象添加where条件private function operator($symbol,$value){if($this->isVoid){throw new Exception("no object field defined");
        }$this->currentfield->addTest($symbol,$value);return $this;                                     //采用连贯语法    }    //获取此类中所有字段对象集合的where条件数组function getComps(){$ret = array();foreach($this->fields as $key => $field){$ret = array_merge($ret,$field->getComps());
        }return $ret;
    }
}//数据映射器class DomainObjectAssembler {protected static $PDO;    //PersistenceFactory本例中并未实现,按原书的说法读者自己完成
    //其主要功能就是生成相应类型的选择工厂类、更新工厂类或Collection对象
    //在初始化的时候根据传入的PersistenceFactory对象决定了这个类是映射那个数据库表和领域模型的function __construct (PersistenceFactory $factory){$this->factory = $factory;if(!isset(self::$PDO)){$dsn = wooaseApplicationRegistry::getDSN();if(is_null($dsn)){throw new wooaseAppException("NO DSN");
            }
            self::$PDO = new PDO ($dsn);
            self::$PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
        }
    }    //获取预处理对象,用sql语句本身做为对象数组的键function getStatement($str){if(!isset($this->statements[$str])){$this->statements[$str] = self::$PDO->prepare($str);
        }return $this->statements[$str];
    }    //根据where条件返回一条数据function findOne(IdentityObject $idobj){$collection = $this->find($idobj);return $collection->next();
    }    //根据where条件返回一个数据集合function find(IdentityObject $idobj){$selfact = $this->factory->getSelectionFactory();             //获取选择工厂对象list($selection,$values) = $selfact->newSelection($idobj);    //获取sql语句$stmt = $this->getStatement($selection);                    //获取预处理对象$stmt->execute($values);                    $raw = $stmt->fetchAll();return $this->factory->getCollection($raw);                    //还记得Collection对象吗,下面粘出代码回顾一下    }    //根据where条件插入或更新一条数据function insert(woodomainDomainObject $obj){$upfact = $this->factory->getUpdateFactory();        //获取更新工厂对象list($update,$values) = $upfact->newUpdate($obj);    //获取sql语句$stmt = $this->getStatement($update);                //获取预处理对象$stmt->execute($values);if($obj->getId()<0){                                    $obj->setId(self::$PDO->lastInsertId);
        }$obj->markClean();
    }
    
    
}/*这里在回顾一下Collection类,当然这个类和上面使用的Collection类是有差别的,因为至少这里的Mapper类与之前相比发生了一些变化
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";
    }
}//客户端
//初始化一个能够获取venue类型的选择工厂类、更新工厂类或Collection对象的超级工厂类$factory = woomapperPersistenceFactory::getFactory("woo\domain\Venue");    
$finder = new woomapperDomainObjectAssembler($factory);        //数据映射器$idobj = $factory->getIdentityObject()->field('name')->eq('The Eyeball Inn');    //设置where条件语句$collection = $finder->find($idobj);                    //根据where条件查找一个数据集合(一个Collection对象)foreach($collection as $venue){                            print $venue->getName()."
";
}

 

睿拓智能网站系统-网上商城
睿拓智能网站系统-网上商城

睿拓智能网站系统-网上商城1.0免费版软件大小:5M运行环境:asp+access本版本是永州睿拓信息专为电子商务入门级用户开发的网上电子商城系统,拥有产品发布,新闻发布,在线下单等全部功能,并且正式商用用户可在线提供多个模板更换,可实现一般网店交易所有功能,是中小企业和个人开展个人独立电子商务商城最佳的选择,以下为详细功能介绍:1.最新产品-提供最新产品发布管理修改,和最新产品订单查看2.推荐产

下载

相关文章

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.2万人学习

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

共6课时 | 11.3万人学习

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

共13课时 | 0.9万人学习

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

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