ugrás a tartalomhoz

Hogy kell ezt a legjobban csinálni?

szabo.b.gabor · 2010. Nov. 8. (H), 18.01
Sziasztok!

kényes témát fogok érinteni, ilyen szereplők jönnek elő a történetben, mint globális változók, singletonok..

szóval van egy alkalmazás, egy-egy funkció viszonylag sok egyéb 'réteget' használ, ezen rétegeket egy-egy osztály valósítja meg, amiknek a példányosítása elég költséges lehet.

tehát mondjuk vannak ilyeneim:
-adatbázis > DB()
-elérési utak > Path()
-config értékek > Config()
-belépett júzer > Auth()
stb..

-tehát ha van egy függvényem ami adatbázist piszkál, nem szeretném benne példányosítani a DB osztályomat, mert nem szeretném hogy ismét kapcsolódjon ahhoz az adatbázishoz, amit nemrég egy másik függvény használt
-ha szükségem van egy elérési útra ugyanolyan jó lesz nekem a húsz függvénnyel előbb példányosított Path osztályban kiszámolt elérési út.
-ha tudni szeretném hogy éles vagy tesztrendszerben vagyok-é, akkor jó nekem ha ugyanazt az értéket kapom vissza, amit másnak már visszaadtak
-ha tudni szeretném, hogy be van-e lépve a júzer, ... stb
itt ugye nyilván egy oldal generálásáról van szó.

nem szeretném ezeket az objektumokat paraméterekben dobálni, biztosan nem tartoznak oda.

eddig azt csináltam, hogy példányosítottam egy osztályt a global névtérben vagy hol, aztán ha kellett valahol, akkor global $_DB, aztán jónapot. engem a $_GET változó léte sem zavar, így hát ez sem bántja a szemem nagyon.

de azért érzem, hogy nem szép ez így, ki tudja mi van a változók mögött.. stb. hogyan lehet ezt szépen megoldani úgy, hogy ne legyen izzadtságszaga?

Singleton? annyian fikázzák, hogy nem merek belevágni anélkül, hogy más lehetőségnek ne néznék utána.

Singletonnál ugye annyi lenne, hogy global $_DB; helyett írok annyit, hogy $_DB=DB::getInstance(); és a meglévő kódom már futna is.. a gáz ezzel az, hogy egyrészt többet kell gépelnem :))) na jó ez vicc, másrészt, ha ugyanezt az osztályt fel akarnám használni egy másik adatbáziskapcsolat kezelésére párhuzamosan, akkor bukó van.

oké meg lehet oldani, hogy ne az osztályom döntsön arról, hogy ő most mi
http://phpgoodness.wordpress.com/2010/07/21/singleton-and-multiton-with-a-different-approach/
megéri??

tehát ki hogyan csinálja, csinálná? olyan egységek kialakítása a feladat, amiknek van egy költségesen előállított állapotuk (meglévő adatbáziselérés, abszolut elérési utak listája, szerverfüggő konfig értékek, júzer paraméterek), ezeket széles körben használjuk, de az állapotukat igazából nem változtatjuk (egy lekérdezés nem vált adatbázis kapcsolatot, ahogy az elérési utak sem változnak, stb..)

hogy lehet mindezt egyszerűen és szépen csinálni?

köszönöm
 
1

Yii féle megoldás

Roberto · 2010. Nov. 8. (H), 19.12
A Yii keretrendszerben tipikusan ilyen feladatra használjuk az ApplicationComponent-eket.

http://yiiframework.com/doc/api/1.1/CApplicationComponent

A leszármazottaknál láthatod még az egyéb alkalmazási területeket is.

A komponensek tulajdonságai config fájlokból állíthatóak, használatban meg kb. így néz ki:

Yii::app()->db->createCommand('SELECT * FROM blah')->query();
2

Szerintem nem kell félni a singletontól

szaky · 2010. Nov. 8. (H), 20.22
Én is sokhelyen olvastam, hogy egyesek fáznak az egykéktól, főleg olyanok, akik nem-php -s környezetből jönnek (pl java), mindenféle indokkal. Én nem értek ezzel egyet. Egy webes-php-s környezet elég speciális abban, hogy az objekumok egy lekérdezésig élnek (jó, tudom, ez nem feltételnül igaz, de most tekintsünk el ettől). Épp ezért nem szabad, nem is helyes bonyolult, nagy mélységű obj-hierarhiát létrehozni, feleslegesen példányosítani többszáz objektumot. Egyszerűen más doktrínák szerint kell dolgozni, inkább lapos, széles, jól skálázható, optimalizálható rendszert kell létrehozni, ahol csak lehet, visszanyesni a túlburjánzó struktúrákat. Ennek egy módszere a singleton, (ill a registry). Nem kell félni tőle, nem az ősgonosz. Természetesen megvannak a hátulütői, nem szabad úton-útfélen használni, tipikusan a rendszer magját érintő, főbb funkciót érdemes beletenni (DB, path, conf - amiket említettél.) A több adatbázis elérés igy egyszerű, pl így:
$_DB_Slave=DB::getInstance('slave')
De ez már a registry felé vezet.
3

Szerintem úgy a legjobb, ha

inf · 2010. Nov. 8. (H), 22.52
Szerintem úgy a legjobb, ha egyetlen singleton-ból vagy multiton-ból lehet elérni az összes olyan dolgot, amit globálisan használni szeretnél.

pl:

Server::Instance()->getSession();
Server::Instance()->getConfig();
Server::Instance()->getController();
//...
4

Dependency Injection Container

firith · 2010. Nov. 14. (V), 23.54
Én a dependency injection-t tartom a legkényelmesebbnek, ha van időd, nézz ennek utána itt: http://components.symfony-project.org/dependency-injection/ remek leírás és nagyon jól használható komponens, nem csak a symfonyban, saját alkalmazásodban is használhatod.

A service container úgy működik mint egy registry, és tárolhatsz benne "sima" objektumot illetve singleton-t is (shared object)

mindenképp érdemes elolvasni! :)
5

Statikus osztályok.

tlof · 2010. Nov. 15. (H), 11.17
Én erre a célra statikus osztályokat használok.
A config osztályomnak pl van egy get metódusa, ami kb igy néz ki:

class Config
{
	private static $start = false;
	private static $config = array();

	public static function get($block)
	{
		if (!self::$start)
		{
			self::$config = self::loadConfig('config');
			self::$start = true;
		}
		if (!isset(self::$config[$block]))
		{
			self::$config[$block] = self::loadConfig($block);

		}
		return self::$config[$block];
	}

	public static function loadConfig($file)
	{
		if (is_file(_APP_DIR . $file))
		{
			$app_conf = parse_ini_file(_APP_DIR . $file, true);
			return $app_conf;
		}
		return null;
	}
}
(a loadConfig részt kicsit kiegyszerüsitettem, de alapjában véve ez a müködési mehanizmusa.)
Ugyan ez igaz az összes kiszolgáló osztályra is, db-re, session-re mindenre.

Ráadásul igy a php autoload mehanizumusát is jó lehet használni, és tényleg csak azok a komponensek kerülnek betöltésre, amik szükségesek.