프로토타입 패턴은 생성자 패턴으로, 새 인스턴스를 만드는 대신 기존 인스턴스를 "복사"하여 새 인스턴스를 반환하는 것이 특징입니다. 이 기사에서는 프로토타입 모드에 대한 자세한 설명을 예제와 함께 제공하여 모든 사람에게 도움이 되기를 바랍니다.
프로토타입 패턴의 주요 역할
추상 프로토타입(Prototype) 역할: 자신을 복제하는 인터페이스를 선언
Concrete Prototype(Concrete Prototype) 역할: 자체 복제하는 연산을 구현
클래스가 거의 동일한 경우 일부 부분만 다른 경우 이 클래스의 개체가 많이 필요한 경우 매번 동일한 부분을 반복적으로 인스턴스화하는 것은 매우 비용이 많이 듭니다. 그러나 개체의 동일한 부분을 복제하기 전에 생성하면 비용이 많이 들 수 있습니다. 구원받다.
PHP의 한 가지 구현 방법은 __construct() 및 초기화 함수를 사용하여 이 클래스의 초기화를 별도로 처리하는 것입니다. 프로토타입은 공용 부분인 구성에 배치되고 각 객체의 특수 부분은 초기화에 배치됩니다. 이런 방식으로 먼저 클래스를 초기화하지 않고 생성한 다음, 클래스를 복제할 때마다 초기화합니다.
이는 zend Framework의 공식 매뉴얼 http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html에 언급되어 있지만 자세히 설명하지는 않습니다. 아래에서 분석해 보세요
1. 소개
zf2 모델에는 데이터베이스 작업을 수행하는 보조 클래스에 해당하는 albumTable 클래스가 있으며 여기에 tablegateway가 사용됩니다.
앨범테이블을 매번 동일한 클래스로 초기화하기 위해 초기화 작업은 팩토리 모드를 사용하는 루트 디렉토리에 있는 module.php 파일의 getServiceConfig()에 들어가고, 매번 콜백 함수를 통해 ServiceManager($sm) 개체를 인스턴스화해야 할 경우 자동으로 호출되어 alumniTable을 생성합니다. 아래 코드를 보면 동일한 방식으로 albumTable을 생성하려면 AlbumTableGateWay를 생성해야 한다는 것을 알 수 있습니다.
2. 자세한 코드 설명
public function getServiceConfig() { return array( 'factories' => array( 'Album\Model\AlbumTable' => function($sm) { $tableGateway = $sm->get('AlbumTableGateway'); $table = new AlbumTable($tableGateway); return $table; }, 'AlbumTableGateway' => function ($sm) { $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter'); $resultSetPrototype = new ResultSet(); $resultSetPrototype->setArrayObjectPrototype(new Album());//这个就是一个不变的原型 return new TableGateway('album', $dbAdapter, null, $resultSetPrototype);//传入到TableGateWay的构造函数中去 }, ), ); }
TableGateWay에서 사용하는 프로토타입 모드가 아니라 ResultSet 클래스라는 점에 유의하세요. tablegateway가 select() 또는 insert()와 같은 메소드를 호출할 때마다 결과를 나타내기 위해 ResultSet이 생성되며 이러한 ResultSet의 공통 부분이 복제되고 데이터와 같은 고유한 부분 클래스가 초기화됩니다.
3. 추가 코드 예제
이 프로토타입을 더 명확하게 이해하기 위해 zend의 큰 프레임워크는 제쳐두고 전체 코드 예제를 살펴보겠습니다.
PHP 생성자 모범 사례 및 프로토타입 패턴<의 예 ;/a>
프로토타입 패턴에 대한 이 기사의 전반부는 실제로 확장성을 향상하기 위해 생성자에서 상속을 사용하는 방법을 혼합한 것입니다. 최종 코드를 직접 살펴보겠습니다. 프로토타입 패턴의
<?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 코드에 있는 클래스에 해당합니다.
Dbadapter -- adpater
RowGateWay -- ResultSet
UserRepository - TableGateWay
자세한 내용은 코드의 주석을 참조하세요.
여기서 RowGateWay는 getusers에서 많은 수의 인스턴스화가 필요하다는 것을 명확하게 볼 수 있으므로 프로토타입 모드가 매우 필요합니다.
다음은 이 클래스를 사용하기 위한 코드입니다
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의 생성자 프로토타입 패턴에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!