Rumah >pembangunan bahagian belakang >tutorial php >Corak Singleton: direka untuk kecekapan

Corak Singleton: direka untuk kecekapan

PHPz
PHPzasal
2023-08-31 13:53:131009semak imbas

Corak Singleton: direka untuk kecekapan

Dalam artikel ini, anda akan belajar cara melaksanakan corak reka bentuk Singleton, dan mengapa dan bila untuk menggunakan corak ini dalam aplikasi anda. Seperti yang dicadangkan oleh nama "Singleton", kaedah ini membolehkan kami mencipta satu objek kelas.

Mari lihat apa yang Wikipedia katakan tentang corak reka bentuk ini:

Corak tunggal ialah corak reka bentuk yang mengehadkan instantiasi kelas kepada satu objek. Ini berguna apabila hanya satu objek diperlukan untuk menyelaraskan operasi keseluruhan sistem.

Seperti yang dinyatakan dalam definisi di atas, apabila kita ingin memastikan bahawa mana-mana kelas perlu mencipta satu dan hanya satu objek, maka kita harus melaksanakan corak Singleton untuk kelas tersebut.

p>

Anda mungkin bertanya mengapa kami perlu melaksanakan kelas sedemikian yang membolehkan kami mencipta hanya satu objek daripadanya. Saya akan mengatakan bahawa kita boleh menggunakan corak reka bentuk ini dalam banyak kes penggunaan. Ini termasuk: kelas konfigurasi, kelas sesi, kelas pangkalan data, dsb.

Dalam artikel ini saya akan mengambil kelas pangkalan data sebagai contoh. Pertama, kita akan melihat masalah yang boleh timbul jika corak tunggal tidak dilaksanakan untuk kelas sedemikian.

soalan

Bayangkan kelas sambungan pangkalan data yang sangat mudah, sebaik sahaja kami mencipta objek kelas ini, ia mewujudkan sambungan ke pangkalan data.

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);
		
	}
	
}

Dalam contoh kod di atas, anda boleh melihat bahawa setiap kali objek kelas ini dicipta, ia mewujudkan sambungan dengan pangkalan data. Jadi jika pembangun mencipta objek kelas ini di beberapa tempat, bayangkan bilangan sambungan pangkalan data (sama) yang akan dibuatnya dengan pelayan pangkalan data.

Oleh itu, pembangun tanpa disedari melakukan kesilapan yang memberi kesan besar pada kelajuan pangkalan data dan pelayan aplikasi. Mari kita lihat perkara yang sama dengan mencipta objek berbeza kelas ini.

$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]

Jika anda melihat output dan output kod di atas, anda boleh melihat bahawa setiap objek diberikan ID sumber baharu, jadi semua objek adalah rujukan baharu, jadi ia turut memperuntukkan memori berasingan. Dengan cara ini, aplikasi kami secara tidak sedar akan menduduki sumber yang sebenarnya tidak diperlukan.

Penyelesaian

Cara pembangun menggunakan rangka kerja asas kami adalah di luar kawalan kami. Sebaik sahaja proses semakan kod berlaku, ia berada di bawah kawalan kami, tetapi kami tidak boleh sentiasa berdiri di belakangnya semasa pembangunan.

Untuk mengatasi situasi ini, kita harus menjadikan kelas asas kita mustahil untuk mencipta berbilang objek kelas sebaliknya, ia akan memberikan objek yang telah dibuat (jika ada). Dalam kes ini, kita harus mempertimbangkan untuk membangunkan corak tunggal untuk kelas asas kita.

Apabila melaksanakan corak ini, matlamat kami adalah untuk membenarkan penciptaan objek satu kelas hanya sekali. Sila benarkan saya menambah kod kelas di bawah dan kemudian kami akan meneliti setiap bahagian kelas secara terperinci.

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
	}
	
}

Ada sedikit petunjuk bahawa kelas di atas adalah kelas Singleton. Pertama ialah pembina peribadi, yang menghalang penciptaan objek menggunakan kata kunci baharu. Petunjuk lain ialah pembolehubah ahli statik yang memegang rujukan kepada objek yang dicipta.

$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]

Jika anda membandingkan output kedua-dua bahagian, maka anda akan melihat bahawa dalam output mod tunggal, ID sumber objek adalah sama untuk semua objek yang berbeza. Tetapi ini tidak berlaku apabila tidak menggunakan corak reka bentuk.

Sarung tunggal sebagai anti-corak

Corak reka bentuk ini juga dipanggil anti-corak untuk pelbagai sebab, yang akan saya sebutkan di bawah:

  1. Memandangkan ia mengawal kualiti ciptaan dan kitaran hayatnya sendiri, ia melanggar Prinsip Tanggungjawab Tunggal.
  2. Ia memperkenalkan keadaan global ke dalam aplikasi anda. Saya akan mengatakan keadaan global sangat buruk kerana sebarang kod boleh mengubah nilainya. Oleh itu, adalah sukar untuk mencari bahagian kod yang telah membuat pembolehubah global peringkat semasa semasa penyahpepijatan.

  3. Jika anda melakukan ujian unit, singleton biasanya merupakan idea yang tidak baik, dan tidak melakukan ujian unit biasanya idea yang tidak baik juga.

KESIMPULAN

Saya cuba sedaya upaya untuk menerangkan corak rekaan singleton yang banyak dibincangkan di internet. Saya harap artikel ini berguna kepada anda. Kami telah merangkumi dua aspek corak ini, corak reka bentuk dan anti-corak.

Sila hantar komen, cadangan dan/atau soalan anda di bawah dan saya akan membalas secepat mungkin. Anda juga boleh menghubungi saya di Twitter @XpertDevelopers atau e-mel terus kepada saya.

Atas ialah kandungan terperinci Corak Singleton: direka untuk kecekapan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn