Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erklärung des Konstruktor-Prototypmusters in PHP

Detaillierte Erklärung des Konstruktor-Prototypmusters in PHP

*文
*文Original
2017-12-28 15:42:301691Durchsuche

Prototypmuster ist ein Erstellermuster, das dadurch gekennzeichnet ist, dass eine vorhandene Instanz „kopiert“ wird, um eine neue Instanz zurückzugeben, anstatt eine neue Instanz zu erstellen. Dieser Artikel enthält eine detaillierte Erklärung des Prototypmodus mit Beispielen. Ich hoffe, dass er für alle hilfreich ist.

Hauptrollen im Prototypmuster

Abstrakter Prototyp (Prototyp) Rolle: Deklarieren Sie eine Schnittstelle, die sich selbst klont
Konkreter Prototyp (Konkreter Prototyp) Rolle : Implementieren Sie eine Operation zum Selbstklonen

Wenn der größte Teil einer Klasse gleich ist und nur einige Teile unterschiedlich sind und eine große Anzahl von Objekten dieser Klasse benötigt wird, ist es sehr teuer, dieselben Teile zu instanziieren Jedes Mal wiederholt, und wenn Sie vor dem Klonen dieselben Teile des Objekts erstellen, können Sie Aufwand sparen.

Eine Implementierungsmethode für PHP besteht darin, dass die Funktionen __construct() und initialize die Initialisierung dieser Klasse separat behandeln. Der Prototyp wird im Konstrukt, dem öffentlichen Teil, platziert, und der spezielle Teil jedes Objekts wird platziert in initialisieren. Auf diese Weise erstellen wir zunächst eine Klasse, ohne sie zu initialisieren, klonen dann diese Klasse und initialisieren sie jedes Mal.

Dies wird im offiziellen Handbuch des Zend Frameworks http://framework.zend.com/manual/2.0/en/user-guide/database-and-models.html erwähnt, aber nicht im Detail erklärt . Ich werde es unten erklären.

1. Einführung

Es gibt eine AlbumTable-Klasse im zf2-Modell, die einer Assistentenklasse für den Datenbankbetrieb entspricht Aktionen und Tablegateway werden darin verwendet.

Um die Albumtabelle jedes Mal mit derselben Klasse zu initialisieren, wird die Initialisierungsarbeit in getServiceConfig() der Datei module.php im Stammverzeichnis, wo der Factory-Modus verwendet wird, und über den Rückruf platziert Funktion, wenn der ServiceManager ($sm) Wenn ein Objekt instanziiert werden muss, wird es automatisch aufgerufen, um eine alumniTable zu erstellen. Aus dem folgenden Code können wir ersehen, dass zum Erstellen einer AlbumTable auch ein AlbumTableGateWay auf die gleiche Weise erstellt werden muss. Diese Klasse verwendet das Prototypmuster, über das wir sprechen werden.

2. Detaillierte Code-Erklärung


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的构造函数中去
        },
      ),
    );
  }


Beachten Sie, dass TableGateWay nicht verwendet wird Prototypenmuster, aber die ResultSet-Klasse wird verwendet. Immer wenn das Tablegateway Methoden wie select() oder insert() aufruft, wird ein ResultSet erstellt, um das Ergebnis darzustellen. Die gemeinsamen Teile dieser ResultSets werden geklont und eindeutige Teilklassen wie Daten werden initialisiert.

3. Weitere Codebeispiele

Um diesen Prototyp besser zu verstehen, lassen wir das große Framework von Zend beiseite und schauen uns ein vollständiges Codebeispiel an. Beispiel aus

29d1381573989fde6caa3ba7028e54fcPHP Constructor Best Practices Und das Prototypmuster5db79b134e9f6b82c0b36e0489ee08ed

Die erste Hälfte dieses Artikels über Prototypmuster ist eigentlich eine Mischung aus der Verwendung von Vererbung in Konstruktoren zur Verbesserung der Skalierbarkeit. Die beiden Muster scheinen sich nicht sehr zu ähneln. Es ist leicht zu verstehen. Schauen wir uns den Prototypmusterteil des endgültigen Codes direkt an.


<?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, &#39;user&#39;)
  }
  public function getUsers() {
    $rows = array();
    foreach ($this->dbAdapter->fetchAllFromTable(&#39;user&#39;) as $rowData) {
      $rows[] = $row = clone $this->rowGatewayPrototype;
      $row->initialize($rowData);
    }
    return $rows;
  }
}


Diese Klassen entsprechen tatsächlich den Klassen im Zend-Code oben

Dbadapter - - adpater

RowGateWay – ResultSet

UserRepository – TableGateWay

Weitere Informationen finden Sie in den Kommentaren im Code.

Der RowGateWay hier kann deutlich erkennen, dass in Getusers eine große Anzahl von Instanziierungen erforderlich ist, sodass der Prototypenmodus sehr wichtig ist.

Das Folgende ist der Code zur Verwendung dieser Klasse


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, &#39;user&#39;)
);
$users = $userRepository->getUsers();
$user = $users[0]; // instance of ReadWriteRowGateway with a specific row of data from the db


Verwandte Empfehlungen:

Detaillierte Erläuterung des Adaptermusters von PHP-Designmustern

Detaillierte Erläuterung des Iteratormusters von PHP-Designmustern Muster

Detaillierte Erläuterung des Beobachtermusters des PHP-Entwurfsmusters

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung des Konstruktor-Prototypmusters in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn