Autor Zpráva
jogurt
Profil
Dobrý večer,
mám takový spíše obecný dotaz. S OOP teprve začínám, tak se omlouvám, jestli je to dotaz pitomý.

Mám tři různé třídy (Auth - přihlašování, Message - zprávy uživateli, Web - hlavní třída se vším možným, ještě z toho snad něco oddělím).
V indexu si vytvořím tři objekty těchto tříd:
$web=new Web();
$message=new Message();
$auth=new Auth();
(...pak ještě třídy nějakých modulů)

Na problémy však narážím, když chci používat atributy nebo metody z jednoho objektu v druhém.
Například mám $auth->logged_user a chci ho použít v nějaké metodě v třídě Web.
Můžu to předávat v parametru ($web->admin_form($auth->logged_user)), ale když je toho hodně, už to není moc pohodlné řešení.
Jak to řešíte vy, zkušení v OOP? Jak to dělat elegantně? Zkuste to prosím popsat jako pro někoho skoro bez zkušeností s OOP. A také obecně, moje kódy jsou jen ilustrační.
Lamicz
Profil
Obecně se to řeší nějakým kontejnerem, např. http://doc.nette.org/en/dependency-injection. Možná zde zkušenější dají lepší příklad, mne jako první napadlo toto. Jako první věc bych navrhl celou strukturu v OOP, protože pár OOP komponent v procedurálním kódu je nanic, s tím se nedá plně využít OOP.
Jan Tvrdík
Profil
jogurt:
Jedním z možných řešení je dependecy injection.

Lamicz:
DI kontejner pro jednoduché weby zbytečný overhead.
jogurt
Profil
Co znamená celá struktura v OOP?
Mám teď v indexu prakticky jen
<?
require("config.php");
require("classes/class.web.php");
require("classes/class.auth.php");
require("classes/class.message.php");

$web=new Web();
$message=new Message();
$auth=new Auth();

### obsluha přihlášení a odhlášení
if(@$_POST['action']=='login') $auth->login(...);
if(isset($_GET['logout'])) $auth->logout();

?><!DOCTYPE html>
...
a pak už jen vypisuji, například...
<title><? echo $web->title; ?></title>
Tyto atributy se vytváří v konstruktoru třídy Web. Takže snad ještě ta obsluha auth by se tam dala také přesunout, pak už netuším, jak by se to dalo napsat víc objektově. To je právě to, v čem bych potřeboval trochu postrčit.

Článek o DI na nette.org jsem četl, když jsem se snažil naučit Nette, ale bylo toho na mě příliš moc nového (bohužel jsem vlastníkem pouze průměrného lidského mozku).
Na odkaz od Jana Tvrdíka se podívám.

Ještě k tomu kontejneru: Jedná se o to, že bych měl všechny objekty vytvořit uvnitř jediné třídy? Prosím, zkuste mi nějak zhruba nastínit, jak by to mělo vypadat.
Jan Tvrdík
Profil
jogurt:
Ještě k tomu kontejneru
Jde o to, že každá aplikace by měla mít právě jeden composition root. To je jediné místo v aplikace, kde můžeš vytvářet instance přímo pomocí volání new. Všude jinde by se závislosti měli předávat pomocí DI. V reálných aplikacích bývá spousta tříd a ještě více závislostí mezi nimi. Dependency Injection Container je nástroj, který pomáhá s vytvářením instancí (včetně všech závislostí) a není nezbytnou součásti DI. Viz třeba fabien.potencier.org/article/12/do-you-need-a-dependency-injection-container nebo pimple.sensiolabs.org.


Ještě doplním: Samotný DI kontejner je skutečně objekt obsahující uvnitř instance všech tříd, které aplikace používá. Není však určen k tomu, aby s ním vlastní aplikace za běhu pracovala. Předávat celý DI kontejner je antipattern. Viz také www.youtube.com/watch?v=ODcfsRpQ0Pw.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: