Maison > développement back-end > tutoriel php > Modèle Singleton : conçu pour l'efficacité

Modèle Singleton : conçu pour l'efficacité

PHPz
Libérer: 2023-08-31 13:54:01
original
1023 Les gens l'ont consulté

Modèle Singleton : conçu pour lefficacité

Dans cet article, vous apprendrez comment implémenter le modèle de conception Singleton, et pourquoi et quand utiliser ce modèle dans vos applications. Comme le nom « Singleton » l’indique, cette méthode nous permet de créer un seul objet d’une classe.

Voyons ce que Wikipédia a à dire à propos de ce modèle de conception :

Le modèle singleton est un modèle de conception qui limite l'instanciation d'une classe à un seul objet. Ceci est utile lorsqu'un seul objet est nécessaire pour coordonner le fonctionnement de l'ensemble du système.

Comme mentionné dans la définition ci-dessus, lorsque nous voulons nous assurer qu'une classe doit créer un et un seul objet, nous devons alors implémenter le modèle Singleton pour cette classe.

p>

Vous vous demandez peut-être pourquoi nous devrions implémenter une telle classe qui nous permet d'en créer un seul objet. Je dirais que nous pouvons appliquer ce modèle de conception dans de nombreux cas d'utilisation. Ceux-ci incluent : les classes de configuration, les classes de session, les classes de base de données, etc.

Dans cet article, je prendrai la classe de base de données comme exemple. Tout d'abord, nous examinerons les problèmes qui peuvent survenir si le modèle singleton n'est pas implémenté pour une telle classe.

Question

Imaginez une classe de connexion à une base de données très simple, une fois que nous créons un objet de cette classe, cela crée une connexion à la base de données.

class database {
    
	private $dbName = null, $dbHost = null, $dbPass = null, $dbUser = null;
	
	public function __construct($dbDetails = array()) {
		
		$this->dbName = $dbDetails['db_name'];
		$this->dbHost = $dbDetails['db_host'];
		$this->dbUser = $dbDetails['db_user'];
		$this->dbPass = $dbDetails['db_pass'];

		$this->dbh = new PDO('mysql:host='.$this->dbHost.';dbname='.$this->dbName, $this->dbUser, $this->dbPass);
		
	}
	
}
Copier après la connexion

Dans l'exemple de code ci-dessus, vous pouvez voir qu'à chaque fois qu'un objet de cette classe est créé, il établit une connexion avec la base de données. Ainsi, si un développeur crée des objets de cette classe à plusieurs endroits, imaginez le nombre de (mêmes) connexions à la base de données qu'il créera avec le serveur de base de données.

Ainsi, les développeurs commettent sans le savoir des erreurs qui ont un impact énorme sur la vitesse de la base de données et du serveur d'applications. Voyons la même chose en créant différents objets de cette classe.

$dbDetails = array(
    	'db_name' => 'designpatterns',
		'db_host' => 'localhost',
		'db_user' => 'root',
		'db_pass' => 'mysqldba'
);

$db1 = new database($dbDetails);
var_dump($db1);
$db2 = new database($dbDetails);
var_dump($db2);
$db3 = new database($dbDetails);
var_dump($db3);
$db4 = new database($dbDetails);
var_dump($db4);

// Output
object(database)[1]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[2]
object(database)[3]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[4]
object(database)[5]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[6]
object(database)[7]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[8]
Copier après la connexion

Si vous voyez la sortie et la sortie du code ci-dessus, vous pouvez voir que chaque objet se voit attribuer un nouvel ID de ressource, donc tous les objets sont de toutes nouvelles références, donc une mémoire séparée leur est également allouée. De cette façon, notre application occupera sans le savoir des ressources qui ne sont pas réellement nécessaires.

Solution

La manière dont les développeurs utilisent notre framework sous-jacent est hors de notre contrôle. Une fois le processus de révision du code lancé, il est sous notre contrôle, mais nous ne pouvons pas toujours les soutenir pendant le développement.

Pour surmonter cette situation, nous devrions empêcher notre classe de base de créer plusieurs objets d'une classe, elle donnera un objet déjà créé, le cas échéant ; Dans ce cas, nous devrions envisager de développer un modèle singleton pour notre classe de base.

En implémentant ce modèle, notre objectif est de permettre la création d'objets d'une classe à la fois et uniquement. Veuillez me permettre d'ajouter le code du cours ci-dessous, puis nous passerons en revue chaque partie du cours en détail.

class database {
    
	private $dbName = null, $dbHost = null, $dbPass = null, $dbUser = null;
	private static $instance = null;
	
	private function __construct($dbDetails = array()) {
		
		// Please note that this is Private Constructor
		
		$this->dbName = $dbDetails['db_name'];
		$this->dbHost = $dbDetails['db_host'];
		$this->dbUser = $dbDetails['db_user'];
		$this->dbPass = $dbDetails['db_pass'];

		// Your Code here to connect to database //
		$this->dbh = new PDO('mysql:host='.$this->dbHost.';dbname='.$this->dbName, $this->dbUser, $this->dbPass);
	}
	
	public static function connect($dbDetails = array()) {
		
		// Check if instance is already exists 		
		if(self::$instance == null) {
			self::$instance = new database($dbDetails);
		}
		
		return self::$instance;
		
	}
	
	private function __clone() {
		// Stopping Clonning of Object
	}
	
	private function __wakeup() {
		// Stopping unserialize of object
	}
	
}
Copier après la connexion

Il y a peu d'indications que la classe ci-dessus soit une classe Singleton. Le premier est le constructeur privé, qui empêche la création d’objets à l’aide du nouveau mot-clé. Une autre indication est une variable membre statique qui contient une référence à l'objet créé.

$dbDetails = array(
    	'db_name' => 'designpatterns',
		'db_host' => 'localhost',
		'db_user' => 'root',
		'db_pass' => 'mysqldba'
);

$db1 = database::connect($dbDetails);
var_dump($db1);
$db2 = database::connect($dbDetails);
var_dump($db2);
$db3 = database::connect($dbDetails);
var_dump($db3);
$db4 = database::connect($dbDetails);
var_dump($db4);

// Output

object(database)[1]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[2]
object(database)[1]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[2]
object(database)[1]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[2]
object(database)[1]
  private 'dbName' => string 'designpatterns' (length=14)
  private 'dbHost' => string 'localhost' (length=9)
  private 'dbPass' => string 'mysqldba' (length=8)
  private 'dbUser' => string 'root' (length=4)
  public 'dbh' => object(PDO)[2]
Copier après la connexion

Si vous comparez la sortie des deux parties, vous verrez que dans la sortie du mode singleton, l'ID de ressource objet est le même pour tous les différents objets. Mais ce n’est pas le cas lorsque l’on n’utilise pas de modèles de conception.

Singleton comme anti-modèle

Ce modèle de conception est également appelé anti-modèle pour diverses raisons que je mentionnerai ci-dessous :

  1. Puisqu'il contrôle la qualité de sa propre création et de son cycle de vie, il viole le principe de responsabilité unique.
  2. Il introduit l'état global dans votre application. Je dirais que l'état global est très mauvais car n'importe quel code peut changer sa valeur. Par conséquent, il est difficile de trouver quelle partie du code a créé les variables globales de l’étape en cours lors du débogage.

  3. Si vous effectuez des tests unitaires, les singletons sont généralement une mauvaise idée, et ne pas faire de tests unitaires est généralement également une mauvaise idée.

Conclusion

J'ai fait de mon mieux pour expliquer le modèle de conception singleton qui est largement discuté sur Internet. J'espère que cet article vous a été utile. Nous avons couvert deux aspects de ce modèle, les modèles de conception et les anti-modèles.

Veuillez poster vos commentaires, suggestions et/ou questions ci-dessous et je vous répondrai dans les plus brefs délais. Vous pouvez également me contacter sur Twitter @XpertDevelopers ou m'envoyer un e-mail directement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal