PHP设计模式及在框架设计中的经典应用.ppt_第1页
PHP设计模式及在框架设计中的经典应用.ppt_第2页
PHP设计模式及在框架设计中的经典应用.ppt_第3页
PHP设计模式及在框架设计中的经典应用.ppt_第4页
PHP设计模式及在框架设计中的经典应用.ppt_第5页
免费预览已结束,剩余27页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

php设计模式及在框架设计中的经典应用,目标,了解设计模式与框架 给出一个可行的学习设计模式的方法 介绍几种常见的设计模式,agenda,设计模式简述 框架简述 设计模式与框架 软件开发演进过程 框架要解决的问题 factory singleton register adapter proxy active record mvc,什么是模式?,demo for(int i=0;i100;i+) 主谓宾 我爱你 计算机领域:在特定场景下、解决某一类问题的通用方法 模式分类(参见:posa-1) 架构模式 设计模式 惯用法,为什么要关注设计模式?,向专家学习 向历史学习 大型软件设计、实施必备 沟通交流的语言 薪水+,模式四要素,模式名称(pattern name) 交流、标记 问题(problem) 场景、上下文 解决方案(solution) 解决方法、方案 效果(consequences) 模式应用的效果及使用模式应权衡的问题,框架是什么?,可复用的面向“对象“软件系统 应用程序工具箱 api,函数 框架(framework) 框架 解决特定领域里面具有类似问题的一组相互协作的类 提供解决常见问题的通用组件 为了“复用”已有的解决方案 为了生产效率和可维护性,软件开发演进过程,机器语言、汇编语言 高级语言,面向过程编程 oop、设计模式、元编程 框架、dsl 智能组件? 只描述需求、软件就给您实现了?:) 程序员担当“智能”,设计自己的框架可能面临的问题,创建大量的复杂对象 比较耗资源的对象只希望初始化一次 动态处理大量的配置 适应不同的数据库 希望延迟初始化数据库连接 日志处理 性能监控 .,warning:接下来的代码供示例使用,不具备产品级可用性,场景一,需要在很多函数中调用数据库的操作 假设对数据库的操作已经封装在一个类里面 实现 v0 可以在函数里面调用该类 function foo() $db = new driver_db_mysql(); function bar() $db = new driver_db_mysql(); 问题 如果driver_db_mysql(改名了呢?参数变化了呢?,模式一:factory,工厂模式v0.1 impl class db_factory public static function getinstance() $db =new driver_db_mysql()() return $db; 使用 function foo() $db = db_factory:getinstance() 使用一致的、简单的方式来初始化复杂的对象,场景二,在一个业务流程中要访问数据库资源,发现多次连接数据库,消耗资源。希望只连接接数据库一次 实现v0 全局变量中初始化连接 $db = db_factory:getinstance() 业务访问全局变量 function foo() global $db; 问题 bad smells ?,模式二:singleton,单例模式+工厂模式 impl class db_factory private static $_db; private function _clone() ; private function _construct() public static function getinstance() if(! (self:$_db instanceof driver_db_mysql) self:$_db = new driver_db_mysql(); return self:$_db; 使用 function foo() $db = db_factory:getinstance(); 实例化一个对象、共享连接,场景三,框架中需要保存一些全局的设置或类的实例,保存框架上下文 实现v0 使用系统$globals $globalsdebug = xxx; 使用 function foo() if($globalsdebug) . 问题 bad smells 违反职责srp,模式三:registry,registry+factory impl class registry private static $_instance; / private static $_data = array(); private $_data = array(); /感谢一位同学指出 。用实例变量还是静态变量,依赖于整体的设计。需要对应修改set,get方法 . public static function getinstance() return self:$_instance; . public function set($key, $value) $this-_data$key = $value; public function get($key) return isset($this-_data$key) ? $this-_data$key : null; 使用 $ctx = reistry:getinstance(); $ctx-set(xxxx,oooo) $value = $ctx-get(xxxx“) 使用单实例的全局对象来代替全局的变量,模式三:registry + factory(续),保存读写分离的两个mysql连接 保存 $ctx = registry:getinstance(); $ctx-set(db_read)=db_factory:getinstance(db_read) $ctx -set(db_write)=db_factory:getinstance(db_read) 使用 $dbreadobj = $ctx-get(db_read) $dbwriteobj = $ctx-get(db_write),场景四,需要同时支持mysql和postgresql连接 实现 针对每个数据库,单独写一个驱动实例 db_factory:getmysqldb() db_factory:getpostgresqldb() 问题 如何保持不同db接口的一致性?,模式四:adapter pattern,定义接口 interface idb public function connect(); public function error(); public function errno(); public static function escape_string($string); public function query($query); public function fetcharray($result); public function fetchrow($result); public function fetchassoc($result); public function fetchobject($result); public function numrows($result); public function close(); /接口定义供示例用 ,模式四:adapter pattern(续),针对不同的db实现 driver_db_mysql implements idb private $link; public function connect($server=, $username=, $password=, $new_link=true, $client_flags=0) $this-link = mysql_connect($server, $username, $password, $new_link, $client_flags); public function errno() return mysql_errno($this-link); / ,模式四:adapter pattern(续),adpater+factory 实现 db_factory public static function getinstance($adapter=mysql) /参数化工厂 if(!isset(self:$_db$adapter) | ($_db$adapter instanceof idb) if (include_once drivers/db/ . $type . .php) $classname = driver_db_ .ucfirst( $type); self:$_db$adapter = new $classname; else throw new exception(driver not found); return self:$_db$adapter; 使用 db_factory:getinstance(mysql),场景五,需要延迟初始化一些资源 class usercontroller private $db; /构造函数中初始化资源 function _construct() $this-db = db_factory:getinstance(mysql) public function manages() $sql = “select * from managers“; $users = $tthis-db-getresults($sql); public function foo() echo “haha“ 问题 foo()方法不需要db连接,在构造函数里面去连接数据库是不是额外消耗连接资源?,模式五:proxy,代理模式v1 实现共同的接口 class proxy_db_mysql implements idb private $db; public function query($query) if(!$this-db) $this-db= db_factory:getinstance(mysql) return $this-db-query($query); 延迟初始化、把耗费资源的操作延迟到必须的时候 问题 每个方法都需重写一次?,proxy,代理模式v2 使用magic方法 class proxy_db_mysql private $mysql; public function _call($method,$args) if(!$this-mysql) $this-mysql = db_factory:getinstance(mysql) retrun call_user_func_array( array($this-mysql,$method),$args ); 使用: function foo() $this-proxy-query($sql); v1 和v2这两种方式哪一个更好呢?,场景六,每次我们都需要原生的sql ? function foo() $sql = “select * from users“; 我希望oo,不要有那么多sql 我不懂sql how to ? nosql:),模式六:active record,使用示例 $user = new user(); $user-name = hanyh; $user-address = 北京; $user-save(); or $data = array(name=hanyh,address=beijing); $user-save($data);,active record,实现 class user extend activebase const insert_sql = “insert into user(name,address) values(?,?)“; private $data; protected $fields = array(name,address); public function save($data=array() if(empty($data) $this-db-save(self:insert_sql,$this-data); else $this-db-save(self:insert_sql,$data); private function _set($field,$value) if(in_array($field,$this-fields) $this-data$field = $value; else throw new exception(“$field does not exist“); 基类负责数据库连接、参数合法性校验等等,mvc模式,架构模式中的一种 属于交互系统 场景 用户界面会变换 界面的变换不影响核心功能性代码 有一致的方式来区分并组织好存储、业务、显示相关代码,mvc,mvc框架诞生的11个步骤,区分核心功能和用户交互 model 实现变化通知功能,需要吗? 参考observer模式 设计和实现view 设计和实现c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论