Singleton class vraagje..
Hallo!
Ik ben al een tijdje bezig met OOP, maar nu is mijn oog gevallen op het Singleton design pattern.
Ik heb een beetje rond gelezen en dacht, hier ga ik eens wat mee uitproberen. Wat ik nu wil, is een singleton database class in meerdere classes kunnen gebruiken. Hoe kan ik dit het beste doen?
De code:
Database.class.php
Normaal gesproken roep je hem zo aan:
Maar als ik nu bijvoorbeeld deze database class in meerdere classes wil gebruiken, moet ik dan elke keer als ik een query uit wil voeren die code gebruiken, of kan dit makkelijker?
Ik ben al een tijdje bezig met OOP, maar nu is mijn oog gevallen op het Singleton design pattern.
Ik heb een beetje rond gelezen en dacht, hier ga ik eens wat mee uitproberen. Wat ik nu wil, is een singleton database class in meerdere classes kunnen gebruiken. Hoe kan ik dit het beste doen?
De code:
Database.class.php
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
class Database {
// Store the single instance of Database
private static $m_pInstance;
private function __construct()
{
echo "Constructor called<br />\n";
}
public static function getInstance()
{
if (!self::$m_pInstance)
{
self::$m_pInstance = new Database();
}
return self::$m_pInstance;
}
public function query()
{
echo "Query is called<br />";
}
}
?>
class Database {
// Store the single instance of Database
private static $m_pInstance;
private function __construct()
{
echo "Constructor called<br />\n";
}
public static function getInstance()
{
if (!self::$m_pInstance)
{
self::$m_pInstance = new Database();
}
return self::$m_pInstance;
}
public function query()
{
echo "Query is called<br />";
}
}
?>
Normaal gesproken roep je hem zo aan:
Maar als ik nu bijvoorbeeld deze database class in meerdere classes wil gebruiken, moet ik dan elke keer als ik een query uit wil voeren die code gebruiken, of kan dit makkelijker?
Je kan in de constructor van je andere klasses zoiets doen
$this->db = Database::getInstance();
$this->db = Database::getInstance();
Je kunt ook een centrale klasse maken en daarin al je hoofd objecten aanmaken:
PHP5 geeft objecten als referentie mee dus alle engine objecten zijn dezelfde.
Code (php)
PHP5 geeft objecten als referentie mee dus alle engine objecten zijn dezelfde.
Gewijzigd op 01/01/1970 01:00:00 door Martijn B
Met het idee van Martijn werk je als het ware in een soort context. Engine is je context, de 'leefruimte' van je applicatie. Dan vraag ik mij weer af: is dit handig? Komt het voor dat je binnen 1 applicatie verschillende contexten nodig hebt - verschillende engines? Zo niet, dan is singleton volgens mij handiger omdat je zo de constructor vrij houdt voor parameters voor het object zelf. Daarnaast hoef je je dan bij ingewikkeldere constructies (met call_user..., ReflectionClass::newInstance, PDOStatement::fetch(PDO_CLASS)) niet druk te maken over je wel goed meegegeven context.
Je zou ook eens naar het Registery Pattern kunnen kijken. Eigenlijk is dat ongeveer wat Martijn! doet. Echter kan je er ook voor kiezen om alleen het register Singleton te maken, dan heb je en de voordelen van Singleton (geen vooraf vastgelegde argumenten) en de voordelen van Martijn's implementatie (geen Singleton in tal van klassen te hoeven implementeren)
Last but not least:
Volgens mij de kleinst mogelijke singleton-implementatie in PHP.
Je zou ook eens naar het Registery Pattern kunnen kijken. Eigenlijk is dat ongeveer wat Martijn! doet. Echter kan je er ook voor kiezen om alleen het register Singleton te maken, dan heb je en de voordelen van Singleton (geen vooraf vastgelegde argumenten) en de voordelen van Martijn's implementatie (geen Singleton in tal van klassen te hoeven implementeren)
Last but not least:
Code (php)
Volgens mij de kleinst mogelijke singleton-implementatie in PHP.
Je moet het voorbeeld van mij eigenlijk zien als gereedschapskist van de applicatie.
In de constructor van de engine heb ik (het gereedschap :P):
Tis een webwinkel ;P
Nu bestaat mijn webwinkel uit diverse acties.
Iedere acties is geimplementeerd als klasse.
Deze erft over van een algemene klasse, waarin algemene zaken voor alle acties worden uitgevoerd.
dus:
In de constructor van de engine heb ik (het gereedschap :P):
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$this->oDB = new CMysql;
$this->oUser = new CUser($this);
$this->oStorage = new CStorage;
$this->oCache = new CCache($this);
$this->oCategory = new CCategory($this);
$this->oProduct = new CProduct($this);
$this->oTrolley = new CTrolley($this);
$this->oOrder = new COrder($this);
$this->oForm = new CForm($this);
$this->oMail = new PHPMailer;
?>
$this->oDB = new CMysql;
$this->oUser = new CUser($this);
$this->oStorage = new CStorage;
$this->oCache = new CCache($this);
$this->oCategory = new CCategory($this);
$this->oProduct = new CProduct($this);
$this->oTrolley = new CTrolley($this);
$this->oOrder = new COrder($this);
$this->oForm = new CForm($this);
$this->oMail = new PHPMailer;
?>
Tis een webwinkel ;P
Nu bestaat mijn webwinkel uit diverse acties.
Iedere acties is geimplementeerd als klasse.
Deze erft over van een algemene klasse, waarin algemene zaken voor alle acties worden uitgevoerd.
dus:
Code (php)
Gewijzigd op 01/01/1970 01:00:00 door Martijn B
Je hebt de constuctor van je klasse netjes private gemaakt, maar je zal ook de clone methode nog private moeten maken. Anders kan je dmv het clonen van je object als nog twee verschillende instanties krijgen ondanks dat je het singleton pattern gebruikt.




