dependenci injection jeho použití v NETTE a

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
lubča
Člen | 4
+
0
-

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.

  1. 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).
  2. 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
+
+1
-

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.

  1. 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());
	}
}
  1. 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í.
  2. Ne nezbytně, ale nebudou fungovat „hezký URL adresy“
  3. 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
+
0
-

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)

lubča
Člen | 4
+
0
-

Dík za rady začnu s tím quick staret a pak se ke zbytku prokoušu .Jinak ten příklad toho emailu mi to trochu osvětlil .Ještě se chci zeptat na namespace (jmenné prostory)? -use Nette\Application\UI;- tento kód plně nahrazuje require_once() ?.

Šaman
Člen | 2666
+
0
-

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)