Moi, olen tutustumassa PHP5:n olio-ominaisuuksiin, ja olio-ohjelmointi on muutenkin vielä aika lastenkengissä. Mutta jostainhan sitä on lähdettävä, ja tälläinen ongelma nyt:
Yritän tehdä tietokantarajapintaa (kuinka omaperäinen idea ;) ja sille toteutusta MySQL:lle näin alkuun. Olen määritellyt rajapinnan, pääluokan "jcdl" sekä jcdl aliluokan "jcdlMySQL" joka käyttää rajapintaa. Haluaisin nyt että voisin jcdl rakentajan parametrillä määrätä mitä aliluokkaa käytetään, eli tässä tapauksessa jcdlMySQL:ää, tyyliin näin:
<?php $jcdl = new jcdl('mysql'); ?>
Mutta en keksi kuinka se nyt toteutetaan, alla tärkeimmät kohdat toteutuksesta:
<?php interface jcdlInterface { function connect($addr, $username, $pw, $db); function quote($s); function query($query); //jne. } //Tämä ei toimi näin, mutta pseudona on se mitä haluaisin class jcdl { function __construct($type = 'mysql') { if ($type == 'mysql') { return new jcdlMySQL(); } } } class jcdlMySQL extends jcdl implements jcdlInterface { //toteutus jcdlInterfacelle } ?>
Eli kuinkas tuollaisen sitten toteuttaa, onko koko ajatusmalli väärillä urilla, vai olisiko olemassa jokin helppo kikka millä saisi tehtyä alkuperäisestä jcdl-oliosta jcdlMySQL luokan olion?
Aluksi, itse tykkään aina määritellä näkyvyysalueen selventääkseni, että koodi on PHP5-tyylistä, vaikka public onkin default. Toiseksi, käytä vahvaa vertailua :p. Kolmanneksi, aloita luokkien nimet isolla kirjaimella. Ja sitten itte ratkaisu: Tarvitsetko yhden tietokantayhteyden? Singleton. Mureakuhan puolella oli juttua staattisesta luokasta, ehkä semmoinenkin käy jos olion ei tarvitse säilöä juurikaan dataa, riippuu toteutuksestasi. Tarvitsetko monta tietokantayhteyttä? JCDLDatabaseFactory tms.
Testaamatonta koodia päästä
<?php class JCDLDatabaseFactory { public static getInstance( $dbType ) { $className = 'JCDL' . $dbType; return new $className(); } } // luodaan instanssi JCDLMySQL-luokasta $jcdl = JCDLDatabaseFactory::getInstance( 'MySQL' ); ?>
Käytän ite aina joskus samanlaista luokkaa, jossa pidän suorituksen ajan singletoneja, nimenä SingletonPool ja se siis palauttaa aina olemassa olevan instanssin mikäli semmoinen on jo olemassa. Sen löytää ainakin toistaiseksi tuolta win32ps-koodivinkistäni (ottanen sen pois sieltä tilaa viemästä kunhan kerkeän). MySQL:n kanssa kannattaa muistaa mysql_connectia käyttäessä new_link-parametri jos yhdistää muuten samoilla parametreilla.
parse_ini_fileä kehiin ja käytetyn tietokannan voikin määritellä suoraan asetustiedostossa.
Hyviä pointteja, kiitos vastauksesta. Lähtikin toimimaan mallisi mukaisesti (jos joku muu tuota käyttää niin muuten toimiva esimerkki mutta "public static function getInstance( $dbType )". Singletonista onkin en.Wikipediassa mukavasti juttua:
http://en.wikipedia.org/wiki/Singleton_pattern
Aihe on jo aika vanha, joten et voi enää vastata siihen.