Je správné rozšířit model (Table\Selection) o další metody?

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

Často narážím na problém, kam umístit společný kód, který je používán více presentery.

Zatím to strkám do modelu jako další metody – pokud to souvisí s modelem.

Ale jak to řešit, když jde o výpočet, který potřebuje více než jeden model? Kam s tím?

Díky

mkoubik
Člen | 728
+
0
-

Model neznamená jedna tabulka v db = jedna třída, obvykle je to celá vrstva aplikace o jejímž návrhu stojí za to se trochu víc zamyslet.
Prostě si na to vytvoř další službu (třídu dědící klidně jen \Nette\Object) a pokud potřebuješ při tom výpočtu pracovat i s databází, tak si tam injektni příslušnou Table\Selection.

patriksima
Člen | 58
+
0
-

mkoubik napsal(a):

Model neznamená jedna tabulka v db = jedna třída, obvykle je to celá vrstva aplikace o jejímž návrhu stojí za to se trochu víc zamyslet.

Já si nemyslím, že db = model. A snad jsem to ani nenapsal. Poznámku o zamyšlení vnímám trochu ofenzivně. Snad to ale bylo myšleno dobře = rychlá klávesnice ;)

Prostě si na to vytvoř další službu (třídu dědící klidně jen \Nette\Object) a pokud potřebuješ při tom výpočtu pracovat i s databází, tak si tam injektni příslušnou Table\Selection.

Jakože bych si založit „prázdnou“ službu Helpers například. A volal metody, kterým bych předával co potřebují? Je na to služba vhodná?

mkoubik
Člen | 728
+
0
-

patriksima napsal(a):

Já si nemyslím, že db = model. A snad jsem to ani nenapsal. Poznámku o zamyšlení vnímám trochu ofenzivně. Snad to ale bylo myšleno dobře = rychlá klávesnice ;)

Nemyslel jsem to nijak zle. „Zamyslet se nad modelem“ znamená klasický objektový návrh. Myslel jsem to tak, že v rámci modelu si můžeš vytvářet jakékoliv třídy, jako bys to dělal kdybys žádný framework nepoužíval.

Jakože bych si založit „prázdnou“ službu Helpers například. A volal metody, kterým bych předával co potřebují? Je na to služba vhodná?

Nevím jestli je služba správný název, ale vytvoř si klasickou třídu (nikoliv statickou), které předáš závislosti konstruktorem nebo přes settery a která bude mít patřičné metody. Helpers bych to radši nepojmenovával, zkus najít výstižnější název podle účelu té třídy.

Definovat to v konfiguraci jako službu má cenu, pokud si ji chceš automaticky předávat do presenteru nebo jiných služeb.

patriksima
Člen | 58
+
0
-

Konkrétně mám 4 funkce.

  • jedna dělá nějaké operace nad daty jedné databáze a pak je zapisuje do jiné databáze.
  • druhá počítá nějakou hodnotu z různých dat
  • další generuje fakturu z různých dat
  • čtvrtá se připojuje k mail serveru a transformuje maily a zapisuje do db

Tzn. udělat z nich 4 třídy s jednou metodou, přičemž konstruktoru předám modely a metodě jen doplňující parametry, které konstruktoru kvůli dynamické povaze dát nemůžu? Ona asi rozumnější cesta není, pokud nechci prasit, že?

Ještě doplňující otázka, abychom odpověděli na otázku v titulku. Je správné strkat rozšířující metody do modelu Selection?

Např.

class Pecka extends Selection
{
    public function __construct(\Nette\Database\Connection $connection)
    {
        parent::__construct('pecka', $connection);
    }

    public function getHumanReadable($property)
    {
        switch($property) {
            case 'svestka': $property = 'Švestičky ze zahrádky'; break;
            case 'jabko': $property = 'Shnilé jabko'; break;
        }
        return $property;
    }
}

Editoval patriksima (11. 10. 2012 17:21)

enumag
Člen | 2118
+
0
-

TL;DR

Dávat takové metody do Selection mi připadá jako velmi špatný nápad. Pro tyto účely mám raději vlastní třídu reprezentující tabulku. Selection nereprezentuje tabulku, ale množinu řádků.

https://github.com/fabik/database

Editoval enumag (11. 10. 2012 17:58)

patriksima
Člen | 58
+
0
-

enumag napsal(a):

TL;DR

Dávat takové metody do Selection mi připadá jako velmi špatný nápad. Pro tyto účely mám raději vlastní třídu reprezentující tabulku. Selection nereprezentuje tabulku, ale množinu řádků.

https://github.com/fabik/database

Mě se to taky moc nezdá, ale neumím říct proč. Můžeš to více rozvést?

Filip Procházka
Moderator | 4668
+
0
-

Protože Selection má stav. Voláním metod ho konfiguruješ a čteš výsledek. Proto pro každou operaci a pro každý dotaz na databázi musí být nový. A pokud potřebuješ vždy novou instanci, tak nemůžeš Selection předávat do presenterů a mezi další modely, a používat jeho metody. Ty musíš předávat právě třeba ten Table, který ti bude jednotlivé instance vytvářet. Tyto svoje speciální metody bys měl dát do konkrétních Table. Nebo do speciálních služeb, pokud bude logika složitější.

patriksima
Člen | 58
+
0
-

Díky moc! Vyřešeno.

David Grudl
Nette Core | 8228
+
0
-

Dědit jakoukoliv třídu z Nette s výjimkou těch několika abstraktních vždy zavání. Nedělal bych to.

David Ďurika
Člen | 328
+
0
-

neviem ci poznas https://github.com/fabik/database ale je to zatial (moj nazor) najlepsia nadstavba nad NDB, nie len ze rozsiruje ‚selection‘ ale dokonca mas vlastny active row

Filip Procházka
Moderator | 4668
+
0
-

@achtan Jenomže tohle pouze upravuje chování Selection, není tam bussines logika ;)

David Ďurika
Člen | 328
+
0
-

@HosipLan ako som pisal ‚nadstavba‘, neviem co presne myslis tym business

Filip Procházka
Moderator | 4668
+
0
-

Bussines logika jsou konkrétní implementace konkrétní aplikace, třeba že do databáze smí taková a taková data a taková a taková se načítají a takhle se upravují po načtení atd. V nejjednodušší formě jsou to konkrétní SQL dotazy.

David Grudl
Nette Core | 8228
+
0
-

achtan napsal(a):

neviem ci poznas https://github.com/fabik/database ale je to zatial (moj nazor) najlepsia nadstavba nad NDB, nie len ze rozsiruje ‚selection‘ ale dokonca mas vlastny active row

Nette\Database má v tuto chvíli nevhodný návrh závislostí, objekty reflection a cache u sebe drží Connection, ačkoliv je používají jiné třídy. Jakmile se tohle nějakým refactoringem vyřeší, fabik/database se (bohužel) rozbije. Což je daň za dědění tříd.

David Ďurika
Člen | 328
+
0
-

@David Grudl ja som za refaktoring! ale predpokladam zo to bude tak o 2–3 roky… cize zatial nam nezosta nic ine len pouzivat fabik/database

David Grudl
Nette Core | 8228
+
0
-

Říkám jen tolik, že vytvářet potomky tříd, které k tomu nejsou explicitně určené, s sebou nese značné riziko. Používej si co chceš.

paranoiq
Člen | 392
+
0
-

pokud vytváříte vrstvu nad NDB (nebo čímkoliv jiným), tak raději zvažte, jestli není lepší použít kompozici místo dědění. o mnoho snadněji se to pak udržuje

jansfabik
Člen | 193
+
0
-

Já bych to s těmi problémy s refactoringem závislostí neviděl tak černě. Prostě přidám do ModelManageru nové gettery, pak se trochu upraví mechanismus vyrábění Selection, předávání závislostí rodičovské třídě a možná, že i vyrábění ActiveRow.

Z pohledu uživatele knihovny by pak mělo stačit jen aktualizovat na novou verzi knihovny kompatibilní s novou verzí frameworku. Pravděpodobně nebude muset ani sáhnout do kódu aplikace a díky autowiringu snad ani do config.neon.

Proto jsem taky pro refactoring!