dependenci injection jeho použití v NETTE a
- lubča
- Člen | 4
Ahoj jsem čerstvý uživatel NETTE právě jsem ho překopíroval na server,
takže mám spoustu otázek které= si potřebuji ujasnit.Všechny se týkají
Dependenci Injection(DI) vím že NETTE DI používá. Jde mi o bližší
pochopení.
Pokud bych si chtěl napsat nějaký web s architekturou MVC a chtěl
používat DI tak si nejdřív musím ujasnit jak vypadá třída a jak se kní
přistupuje. Dočetl jsem se že při použití DI má třída na starosti jen
jednu určitou funkci , třeba jen uložení dat do souboru, to jestli data do
třídy dorazila třídu jako takovou nezajímá protože to zkontroluje
CONTROLER a pokud ty data nedorazila tak CONTROLER vyhodí chybu a třídu ani
o odeslání dat žádát nebude a pokud data dorazila ta třída jenb tupě
data uloží?. Data pro třídu by obstarala jiná třída která by zjistila
jejich validitu apod. ale v ukázce jdou data do třídy v proměnné
$content. Vím že na této ukázce není vidět DI ale je to kratší :-).
Jde mi jen o moji ukázku jednoúčelnosti třídy. Rozumím tomu
správně?.
Třída by vypadala takto:
Class FileWrite{
public $path;
private $content;
private $fopen;
private $fwrite;
private $fclose;
public function __construct($path, $content){
$this->path = $path;
$this->content = $content;
}
public function fileWrite(){
$this->open = fopen($this->path,'w');
$this->write = fwrite($this->open,$this->content);
$this->close = fclose($this->open);
return true;
}
}
$path='test-file-write.txt';
$content='ja jsem testovni soubor hbkhsdnflskgmf';
$objfileWrite = new FileWrite ($path, $content);
$objfileWrite->fileWrite();
....
....
....atd atd
Ovšem byl jsem upozrněn na to že to už jsem si rovnou mohl udělat funkci
-function fileWrite()- ve špagetách
protože, vytvořit si třídu kvůli jedné methodě co ukládá data, ještě
neznamená OOP přístup .
Taky mi byla zkritizována třída na odeslání emailu. Má prázdný
konstruktor .Vím že je konstruktor prázdný ale já nevím co bych do něj
dal. Vše přichází od uživatele v $_POST[ˇto]… a ten nepředávám v
$objEmail = new EmailHtml ($_POST[ˇto], $_POST[ˇfrom], $_POST[ˇmessage],
$_POST[ˇsubject]),
protože jsou to globální proměnné a k těm je přístup odevšad tak je
používám přímo a nepředávám je přes konstruktor. Někde jsem četl že
konstruktor se musí vždy uvést i když je prázdný.
Tady je kód pro email:
Class EmailHtml{
private $headers;
public function __construct(){
}
public function extra_mail(){
$_POST['message'] = wordwrap($_POST['message'], 70, "<br>\r\n");
$_POST['message'] ='<b><i><span style="color: green">'.$_POST['message'].'</span></i></b>';
$this->headers = "From:".$_POST['from']." \r\n";
$this->headers .= "Reply-To:".$_POST['from']." \r\n";
$this->headers .= "CC:".$_POST['from']." \r\n";
$this->headers .= "MIME-Version: 1.0 \r\n";
$this->headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
return mail($_POST['to'], $_POST['subject'], $_POST['message'], $this->headers);
}
}
//něco od uživatele
$_POST['to'];
$_POST['from'];
$_POST['subject'];
$_POST['message'];
$objEmail = new EmailHtml ();
$objEmail->extra_mail();
Neříkám že je ta třída na emaily nějak suprová a že se jedná o DI ale furt lepší než špagety a právě proto, že už nechci žádný špagety tak proto jsem přešel na NETTE . Mám za to že mě NETTE naučí líp a slušně pracovat s OOP
Vše bych shrnul do pár otázek.
- je DI jen o jednoúčelné funkci (jen ulož data do souboru maximálně vyhoď chybu když se nezdařilo o ostatní se nestarej to dodá jiná třída).
- jak by vypadaly mé dvě situace v NETTE?. Prosím teoretický výklad a nějaký malý kus kódu pro představu jak NETTE pracuje.
3)Přistupije NETTE k uživatelským proměnným jako k $_POST[subject] nebo
jako $subject = $_POST[subject], prý je správně ta první varianta?.
4)Router se dá použít jen když je povolen soubor htaccess?.
5)Jak jste se začínali učit vy NETTE ?.
6)Lze se s NETTE zcela vyhnout špagetám, maximálně používat jen if else
foreach while for …apod.jinak vše jen Objektově (ve špagetách jen běžné
rozhodovací konstrukce)?
Předem dík za pomoc v začátcích
- Oli
- Člen | 1215
Ahoj,
no řekl bych, že z toho máš tak trochu guláš :-) Zkusím to trochu po
rozkrýt i když to asi nebude úplně přesné snad ti to pomůže.
- Tady vubec nejde o DI. DI je jen způsob jakým způsobem dostane třída
nějaký informace, který nutně potřebuje pro práci. To co popisuješ ty je
SRP.
Ty jsi to dotáhl ad absurdum. Jde o to, že by jsi měl mít třídu, která
třeba má na starosti formulář. Nic jiného ji nezajímá jen vykreslí a
zpracuje odeslaný formulář. V rámci toho zpracování si zavolá jinou
třídu, která uloží informace do databáze (nic jinýho neděla, jen pracuje
s databází) a další třídu, která se stará o odesílání e-mailů. Jde
o to, že potom nemáš jednu třídu, která umí všechno (God class), ale
umí jen jednu věc a ví, kdo další umí věci, které sama potřebuje. Umí
jednu věc neznamená, že má jednu metodu, ale trochu míň specializovaně.
Například umí pracovat s tabulkou „articles“. A má metody
findById($id)
,findAll()
,save($data)
,delete($id)
, … Taková krátká ukázka by mohla vypadat třeba takhle:
class ContactForm extends Control
{
private $mailer;
private $database;
// tohle je v podstatě to DI
public function __construct(Mailer $mailer, ArticleDatabase $database)
{
// nějaká třída, která umí posílat e-maily
$this->mailer = $mailer;
// nějaká třída, která umí pracovat s databází
$this->database = $database;
}
public function createComponentForm()
{
$form = new Form;
// definuješ jak bude formulář vypadat
$form->addText('from', 'Od');
$form->addTextbox('message', 'Zpráva');
$form->addSubmit('send', 'Odeslat');
$form->onSuccess[] = $this->process;
}
public function process(Form $form)
{
// Třída pro práci s databází má metodu save, která zajistí, že se data uloží
// Uložit do databáze, totiž není prací ProcessForm, ale ArticleDatabase
// $form->getValues() je metoda třídy Nette\UI\Application\Form, která vrací očištěný data od uživatele
// žádný $_POST['from'];. Víc o tom je v dokumentaci.
$database->save($form->getValues(TRUE));
// Třídě Mailer předáš data z formuláře. Ta třída potom sama zvládne poslat mail.
$mailer->setData($form->getValues());
}
}
- Nette vůbec nikdy k takovým proměnným nepřistupuje. Tyhle proměnný totiž obsahujou „surový“ data, která můžou obsahovat škodlivý kod. Pro práci s formulářem využij vždy Nette formuláře, který ti data vyčistí.
- Ne nezbytně, ale nebudou fungovat „hezký URL adresy“
- Quickstart je určitě dobrej nápad. Potom pročítání dokumentace a zkoušení metodou pokus omyl. Až pochopíš základy, tak: Planette, poslední sobota, forum, …
- Šaman
- Člen | 2666
Tohle by bylo na dlouhé psaní, jestli chceš, můžeme to probrat po Skype. Nicméně DI a single responsibility principe spolu přímo nesouvisí. Jen bych zdůraznil, že závislostí nemusí být přímo objekt, ale i skalární hodnoty – to by právě mělo být v tom konstruktoru třídy EmailHtml, která by si je pak neměla tahat skrytě z globálního pole.
Editoval Šaman (14. 6. 2015 14:53)
- Šaman
- Člen | 2666
Ne, jmenné prostory vůbec nesouvisí s Nette, o nich si přečti něco
v nějakém PHP tutoriálu (byly přidány v PHP 5.3, takže archaické
tutoriály je neznají).
require
v Nette nahrazuje RobotLoader, případně loader
composeru. To znamená, že když vyžaduješ nějakou třídu,
tento loader ti podle jejího názvu najde soubor, ve kterém je definována (a
ty NS jsou součastí názvu, ale nemusí být, třeba Dibi nemá jmenné
prostory).
To, že jen třídu jsem zdůraznil proto, že pokud bys potřeboval načíst kód ze souboru, který není třída, tak si ho musíš includovat ručně.
Editoval Šaman (14. 6. 2015 16:14)