PHP编程:php示例详解Constructor Prototype Pattern 原型模式
《php示例详解Constructor Prototype Pattern 原型模式》要点: 原型模式中主要角色 抽象原型(Prototype)角色:声明一个克隆本身的接口 当一个类大部分都是相同的只有部分是不同的时候,如果必要大量这个类的对象,每次都重复实例化那些相同的部分是开销很大的,而如果clone之前建立对象的那些相同的部分,就可以节约开销.PHP编程 针对php的一种实现方式便是__construct()和initialize函数分开分别处理这个类的初始化,construct里面放prototype也便是公共的部分,initialize里面是每个对象特殊的部分.这样我们先建立一个类不initialize,以后每次clone这个类再进行initialize就可以了.PHP编程 ?在zend framework官方手册里面提到了这个http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html,但是没有细讲,下面我来阐发一下PHP编程 一、引入PHP编程 在zf2的model里面有一个albumTable类,相当于一个操作数据库动作的助手类,里面用到了tablegateway.PHP编程 为了每次初始化albumtable都是相同的一个类,将初始化工作放到了根目录的module.php文件的getServiceConfig(),其中用到工厂模式,并且通过回调函数,当每次ServiceManager($sm)必要实例化一个对象的时候会自动调用创建一个alumTable.下面代码我们可以看出,创建一个albumTable还必要用相同的方式创建一个AlbumTableGateWay,这个类就用到了我们所要讲的原型模式.PHP编程 二、代码详解PHP编程 public function getServiceConfig() { return array( 'factories' => array( 'AlbumModelAlbumTable' => function($sm) { $tableGateway = $sm->get('AlbumTableGateway'); $table = new AlbumTable($tableGateway); return $table; },'AlbumTableGateway' => function ($sm) { $dbAdapter = $sm->get('ZendDbAdapterAdapter'); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Album());//这个就是一个不变的原型 return new TableGateway('album',$dbAdapter,null,$resultSetPrototype);//传入到TableGateWay的构造函数中去 },),); } 注意并不是TableGateWay运用了原型模式而是ResultSet这个类运用了.每当tablegateway调用select()或者insert()等办法的时候都会建立一个ResultSet用来表示结果,这些ResultSet中公共部分被clone,而独特的部分类如data就会被initialize.PHP编程 三、更多代码示例PHP编程 为了更清晰得了解这个原型,我们先抛开zend这个年夜框架,看一个完整的代码示例.示例来自PHP编程 <a href="http://ralphschindler.com/2012/03/09/php-constructor-best-practices-and-the-prototype-pattern">PHP Constructor Best Practices And The Prototype Pattern</a> 这篇文章关于prototype pattern的部门前半部门其实是混杂怎样在构造函数中运用继承来提高扩展性,两个模式看起来可能不太好理解,我们直接看最后的代码关于prototype pattern的部门.PHP编程 <?php //框架中很常见的adapter类,用来适配各种数据库,封装一些基本数据库连接操作. //相当于上面代码中的adapter类 class DbAdapter { public function fetchAllFromTable($table) { return $arrayOfData; } } //运用prototype pattern的类,注意construct和initialize是分开的 //相当于上面zend 代码里面的ResultSet类 class RowGateway { public function __construct(DbAdapter $dbAdapter,$tableName) { $this->dbAdapter = $dbAdapter; $this->tableName = $tableName; } public function initialize($data) { $this->data = $data; } /** * Both methods require access to the database adapter * to fulfill their duties */ public function save() {} public function delete() {} public function refresh() {} } //相当于上面代码中的TableGateway类,关于gateway可以具体去了解一下. class UserRepository { public function __construct(DbAdapter $dbAdapter,RowGateway $rowGatewayPrototype = null) { $this->dbAdapter = $dbAdapter; $this->rowGatewayPrototype = ($rowGatewayPrototype) ? new RowGateway($this->dbAdapter,'user') } public function getUsers() { $rows = array(); foreach ($this->dbAdapter->fetchAllFromTable('user') as $rowData) { $rows[] = $row = clone $this->rowGatewayPrototype; $row->initialize($rowData); } return $rows; } } 这几个类其实和上面zend代码中的类是对应的PHP编程 Dbadapter -- adpaterPHP编程 RowGateWay -- ResultSetPHP编程 UserRepository - TableGateWayPHP编程 具体看代码中的注释.PHP编程 这里的RowGateWay可以很明显的看出在getusers中需要大量的实例化,那么原型模式就是很需要的了.PHP编程 下面是运用这个类的代码PHP编程 class ReadWriteRowGateway extends RowGateway { public function __construct(DbAdapter $readDbAdapter,DbAdapter $writeDbAdapter,$tableName) { $this->readDbAdapter = $readDbAdapter; parent::__construct($writeDbAdapter,$tableName); } public function refresh() { // utilize $this->readDbAdapter instead of $this->dbAdapter in RowGateway base implementation } } // usage: $userRepository = new UserRepository( $dbAdapter,new ReadWriteRowGateway($readDbAdapter,$writeDbAdapter,'user') ); $users = $userRepository->getUsers(); $user = $users[0]; // instance of ReadWriteRowGateway with a specific row of data from the db 以上内容是小编给年夜家介绍的php示例详解Constructor Prototype Pattern 原型模式,希望年夜家喜欢.PHP编程 编程之家培训学院每天发布《php示例详解Constructor Prototype Pattern 原型模式》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |