Předávání Modelu objektům a zpět

Fires
Člen | 89
+
0
-

zdravím rád bych se zeptal jen na Váš názor ..
Mám model + objekty ktere vytvari
napr:

class blogModel(){

//constructor, injecty atd ..

	public function getAuthorById($id){
	//db query
	return new BlogAuthor($blogAuthorRow,**$this**)
	}
}
class BlogAuthor(){

private $blogModel;
	//constructor, injecty atd ..

	public function save(){
		$this->blogModel(**$this**);
	}

}

Popravdě se mi nějak nelíbí neustále předávání modelu a objektu přes $this, je to tak v pořádku nebo to dělat uplně jinak ? Nikde jsem nenašel žádný example který by odpovídal mé struktuře.

Díky za názory

Editoval Fires (22. 1. 2018 12:34)

iNviNho
Člen | 352
+
0
-

Možno ti pomôže ORM: https://github.com/kdyby/doctrine

V podstate v tvojom prípade by som si to rozdelil takto:
Mal napríklad triedu BlogRepository: Táto trieda by robila všetko čo sa týka práce s DB (add, edit, select, delete). Neobsahuje žiadnu logiku!
Mal napríklad triedu BlogService: Táto trieda by pracovala s BlogRepository a mohla kľudne obsahovať nejakú logiku
Mal napríklad entitu(pri použíti ORM) Blog: Táto trieda by definovala všetky premenné objektu(stlpce v tabuľke) Blog + metódy, ktoré by si potreboval.
A napríklad ak by som chcel formulár, ktorý vie vytvoriť Blog, tak by som si vytvoril BlogFormFactory: Táto trieda by vytvorila formulár pre vloženie Blogu :)

PS1: Určite by som nemal triedu Blog, ktorá by dokázala samého seba aj vložiť do DB. Pri veľkých projektoch je dobré škálovať, rozdeľovať triedy a dávať im iba jednu zodpovednosť (single responsiblity). O vkladanie do DB nech sa stará niekto iný, respektíve iná class.

Editoval iNviNho (22. 1. 2018 12:51)

Šaman
Člen | 2632
+
+1
-

Pro začátek dopoučuji třeba tenhle článek. Byla to přednáška na jedné hodně dávné PoSobotě. Dovolím si tvrdit, že dokud sám nezjistíš, proč tohle používat nechceš, tak je to velmi prehledný a čistý způsob zpracování modelu. I když je článek hodně starý. A taky ti znalost tohoto přístupu pomůže pochopit různá ORM, včetně té Doctrine. (I když ta umožňuje více způsobů, jak k problému přistoupit.)

Fires
Člen | 89
+
0
-

iNviNho napsal(a):

Možno ti pomôže ORM: https://github.com/kdyby/doctrine

V podstate v tvojom prípade by som si to rozdelil takto:
Mal napríklad triedu BlogRepository: Táto trieda by robila všetko čo sa týka práce s DB (add, edit, select, delete). Neobsahuje žiadnu logiku!
Mal napríklad triedu BlogService: Táto trieda by pracovala s BlogRepository a mohla kľudne obsahovať nejakú logiku
Mal napríklad entitu(pri použíti ORM) Blog: Táto trieda by definovala všetky premenné objektu(stlpce v tabuľke) Blog + metódy, ktoré by si potreboval.
A napríklad ak by som chcel formulár, ktorý vie vytvoriť Blog, tak by som si vytvoril BlogFormFactory: Táto trieda by vytvorila formulár pre vloženie Blogu :)

PS1: Určite by som nemal triedu Blog, ktorá by dokázala samého seba aj vložiť do DB. Pri veľkých projektoch je dobré škálovať, rozdeľovať triedy a dávať im iba jednu zodpovednosť (single responsiblity). O vkladanie do DB nech sa stará niekto iný, respektíve iná class.

Diky moc všem za náměty, hned jsem to prošel a už vidím v čem je můj přistup „hloupý“. V podstatě bych tedy šel do 3 úrovní jak tu píšeš

  1. BlogRepository – prace s db
  2. BlogService – logika pro praci s objekty
  3. BlogPost/BlogAuthor/BlogCategory

Je to tak ok ?

Můj postup tedy získání třeba posledních postů bude :

  1. BlogService->getLatestPosts(); ← vrátí pole objektů BlogPost sem to ještě v pohodě chápu

ale teď chci vypsat autory pro jednotlivé články tzn. v latte šabloně.
{$post->getAuthor()->authorName} $post->getAuthor() si zavolá $blogService->getAuthorById($id);
ano či ne ?

Jak předávat závislosti na service ? zase přes this při vytváření objektu nebo blogservice mít jako static metody ?

Šaman
Člen | 2632
+
+1
-

Pro úplný začátek ti stačí Entita a Repository. Jen pro nějaké složitější případy si budeš vytvářet ještě Service, které to obalí (např. UserService která umí resetovat hesla a posílat na email jednorázový odkaz ke změně hesla apod. Ale tohle pro začátek můžeš mít i v presenteru.)

Pokud používáš nějaký ORM, nebo NotORM (tedy i Nette\Database\Table), tak máš možnost traverzování po vazbách přímo od entity, kterou už máš. Takže si vytáhneš $latestPosts a pro každý zjistíš $post->author->name.

Složitější to začne být ve chvíli, kdy máš klasické školní zadání z databází: „Najdi všechny autory žijící ve 20. století, kteří napsali aspoň 3 knížky, které mají hodnocení nad 90%“ Na tohle je lepší si udělat úplně novou třídu, té předat databázi (dibi, connection, context …) a sestavit si ten dotaz ručně. Já těmhle třídám říkám DataSource. To už jsou ale ty případy, kdy ta jednoduchá struktura nestačí.

Extrémně jednoduchý model nad Nette\Database\Table mám tady. Je to starší, ale princip se nemění. V BookRepository si všimni jak se vyhledávají knihy podle autora.
Pravá entita v tomto nejjednodušším případě není, místo toho se pracuje s nějakým objektem result (to, co nativně vrací Nette database). Nad ním se ještě dají volat nějaké dodatečné řazení a limity a tahat z něho přímo výsledky.

Editoval Šaman (22. 1. 2018 13:48)

Fires
Člen | 89
+
0
-

Šaman napsal(a):

Pro úplný začátek ti stačí Entita a Repository. Jen pro nějaké složitější případy si budeš vytvářet ještě Service, které to obalí (např. UserService která umí resetovat hesla a posílat na email jednorázový odkaz ke změně hesla apod. Ale tohle pro začátek můžeš mít i v presenteru.)

Pokud používáš nějaký ORM, nebo NotORM (tedy i Nette\Database\Table), tak máš možnost traverzování po vazbách přímo od entity, kterou už máš. Takže si vytáhneš $latestPosts a pro každý zjistíš $post->author->name.

Složitější to začne být ve chvíli, kdy máš klasické školní zadání z databází: „Najdi všechny autory žijící ve 20. století, kteří napsali aspoň 3 knížky, které mají hodnocení nad 90%“ Na tohle je lepší si udělat úplně novou třídu, té předat databázi (dibi, connection, context …) a sestavit si ten dotaz ručně. Já těmhle třídám říkám DataSource. To už jsou ale ty případy, kdy ta jednoduchá struktura nestačí.

Extrémně jednoduchý model nad Nette\Database\Table mám tady. Je to starší, ale princip se nemění. V BookRepository si všimni jak se vyhledávají knihy podle autora.
Pravá entita v tomto nejjednodušším případě není, místo toho se pracuje s nějakým objektem result (to, co nativně vrací Nette database). Nad ním se ještě dají volat nějaké dodatečné řazení a limity a tahat z něho přímo výsledky.

Diky mrknu na tvoje repo a budu se inspirovat . Nepouzivam nette database ale stare dobre dibi. Nevim proc ale proste mi sedi vice.

Šaman
Člen | 2632
+
0
-

Aha, ukázku v Dibi mám tady Ale je taky dost stará. Teď používám taky Dibi, ale pod LeanMapperem, takže z hlavy ti neřeknu, jestli se v novějších vezrích něco zásadního nezměnilo. To, co je v ukázce, odpovídá těm DataSource, o kterých jsem psal výše. Tedy ručně sestavený dotaz, který zcela obejde ORM (LeanMapper), protože v něm neumím tak složitý dotaz napsat (různé uniony, seskupování, apod.).
Jestli ti jde o použití v jednoduché aplikaci, můžeš zkusit ten LeanMapper
Bohužel už je (myslím) neudržovaný.