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.
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.
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.
Corak reka bentuk ini juga dipanggil anti-corak untuk pelbagai sebab, yang akan saya sebutkan di bawah:
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!