Titluri recente
You are here: Home / Tehnologie / Web / Php-Mysql / Php design pattern: SINGLETON

Php design pattern: SINGLETON

 

Unele resurse in cadrul unei aplicatii php (si nu numai) sunt exclusive: mai exact, nu pot fi instantiate de mai multe ori in cadrul aplicatiei. De exemplu conexiunea la o baza de date; dorim ca orice operatiune asupra tabelelor sa foloseasca aceeasi instanta a obiectului conexiune, altfel aplicatia va fi ingreunata de numarul mare de conectari si deconectari la baza de date.

Paternul SINGLETON ofera aceasta posibilitate. Un obiect este singleton daca aplicatioa poate folosi doar o singura instanta a acestuia. Urmatorul cod, arata o conexiune la baza de date folosing un obiect singleton.

<?php
require_once("DB.php");

class DatabaseConnection
{
	public static $instance = NULL;

	public static function getInstance()
	{
		if (!isset(self::$instance))
		{
			self::$instance = new DatabaseConnection();
		}
		return self::$instance;
	}

	private function __construct()
	{
		$dsn = 'mysql://root:password@localhost/photos';
		$this->instance =& DB::Connect( $dsn, array() );
	}

	public function select()
	{
		...
	}

	public function update()
	{
		...
	}
}

$rezultat_select = DatabaseConnection::getInstance()->select();
$rezultat_update = DatabaseConnection::getInstance()->update();
?>

Codul de mai sus reprezinta o clasa numita DatabaseConnection. Obiectul de tip DatabaseConnection nu se poate crea deoarece constructorul (functia __construct) este de tip privat. Pentru a obtine on obiect de acest tip, se poate folosi metoda statica getInstance().

Variablele $rezultat_select si $rezultat_update folosesc acelas obiect ($instance) de tip DatabaseConnection. Folosind acest tip de apel al obiectului, veti folosi aceiasi conexiune pe caprcursul intregii aplicatii.

Stocarea obiectului intr-o variabila globala, ar putea fi o solutie uitla in cadrul aplicatiilor mici. In cadrul aplicatiilor mai mari, este de evitat folosirea variabilelor globale si se va folosi metoda specifica pentru a apela un obiect singleton.

 

Update:

In urma unor discutii cu anumiti experti php, am ajuns la concluzia ca nu prea este raspandit in ‘randul lumii‘ conceptul de constructor privat.  O sa adaug in continuare un nou exemplu pentru a demonstra intr-un mod cat mai simplu utilitatea unui constructor privat, si din punctul meu de vedere indispensabil in cazul claselor Singleton.

<?php
class Singleton
{
	// singleton object instance
	public static $instance = NULL;

	// class properties
	public 	$foo;
	private $bar;

	//constructor
	private function __construct()
	{

	}

	//get singleton object
	public static function getInstance()
	{
		if (NULL === self::$instance)
		{
			self::$instance = new Singleton();
		}
		return self::$instance;
	}	
}

//create / obtain singleton object
$singleton_object = Singleton::getInstance();
var_dump($singleton_object);

//error 
$fatal_error = new Singleton();
?>

Codul de mai sus, rulat exact asa cum e, va afisa un obiect de tip Singleton, apoi o eroare fatala! Am afisat acel obiect pentru a demonstra ca se poate crea obiect de tip Singleton desi constructorul este privat, dar numai folosind metoda  Singleton::getInstance(); Am afisat eroarea pentru a sublinia utilitatea constructorului privat. Sub nici o forma nu voi putea crea un nou obiect de tip Singleton. De fiecare data cand voi incerca, voi obtine acea eroare, astfel, singura metoda de a folosi aceasta clasa este, getInstance, unde voi obtine acelasi obiect.

Modificarea constructorului din privat in public, va avea ca scop inlaturarea erorii. Dar oare asta imi doresc? Sa am mai multe instante dintr-o clasa Singleton? Tocmai asta nu face acest design-pattern. Nu este gresit, totusi, sa declaram constructorul public, atata timp cat suntem 100% siguri ca nu vom folosi niciodata urmatoarea sintaxa: $un_obiect = new Singleton().  Nu recomand aceasta abordare! Cu siguranta peste ani si ani cand veti folosi acest cod, e posibil sa uitati ca aceasta clasa ati realizat-o pentru a fi singleton. Lasati constuctorul sa va reaminteasca! Faceti-l privat!

About Mihai Adam

Leave a Reply

Your email address will not be published. Required fields are marked *

*


7 − two =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>