プロトタイプパターンはクリエーターパターンであり、新しいインスタンスを作成するのではなく、既存のインスタンスを「コピー」することによって新しいインスタンスを返すことを特徴とします。この記事では、プロトタイプ モードについて例を交えて詳しく説明しますので、皆様のお役に立てれば幸いです。
プロトタイプパターンの主な役割
抽象プロトタイプ(Prototype)ロール:自身を複製するインターフェースを宣言
具象プロトタイプ(Concrete Prototype)ロール:自身を複製する操作を実装
クラスがほぼ同じ場合一部の部分だけが異なる場合、このクラスのオブジェクトが多数必要な場合、毎回同じ部分を繰り返しインスタンス化するのは非常にコストがかかりますが、オブジェクトの同じ部分をクローン作成前に作成すると、コストがかかる可能性があります。救われます。
PHP の実装方法の 1 つは、このクラスの初期化を __construct() と初期化関数で個別に処理することです。プロトタイプはパブリック部分であるconstructに配置され、各オブジェクトの特別な部分はinitializeに配置されます。このようにして、まず初期化せずにクラスを作成し、その後クラスを複製するたびに初期化します。
これはzendフレームワークの公式マニュアル 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 中国語 Web サイトの他の関連記事を参照してください。