Správný návrh modelu oproti presenteru

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

Ahoj,

mám tu trochu objektové dilema. Měl jsem to připravenou na poslední sobotu v Plzni, ale ta je daleko :))

Mám v různé části aplikace vypisovat úlohy podle různého stavu a podmínek (všechni uživatelé, uživatel, pouze podřízení, …, se stavy splněno, nesplněno, po termínu, před termínem, v následujících sedmi dnech, …) a používám tyto data jak v presenteru, tak si je přenáším do komponent.

Teď jdu formou, že na každý tento stav mám v modelu vlastní funkci a volám vždy konkrétní, např.
$this->service->getAllItems($user_id); apod… Je to takto správně? Mnoho těchto metod mají odlišné kombinace podmínek.

Nebo si mám z modelu převzít jen objekt se Selection a Where, Group, Order přidat až v presenteru?

Děkuji

CZechBoY
Člen | 3608
+
0
-

Určitě bych řešil všechny data v modelu a presenter by měl jen předat ty data do šablony.
Kde zjistíš podle čeho filtruješ? Přijde ti to z formuláře nebo je to pevně daný?

igor.pocta
Člen | 100
+
0
-

Filtruji podle tohle, v jaké akci se uživatel nachází… takže pevně dané.

  • pokud je na stránce s výpisem úloh podřízených
  • pokud je to na profilu zaměstnance (seznam úloh) tak tam je komponenta
  • pokud je to pro výpis do emailu, tak tam jsou úlohy na nadcházejících 7 dní + ty po termínu
  • pokud je ve skupině úloh, tam jsou pro změnu úlohy dané skupiny a všechny
  • pak všechny úkoly kde je uživatel jako řešitel nebo spolupracovník …

Právě jak existuje mnoho kombinací podmínek a možností, tak jsem z toho zmaten.

CZechBoY
Člen | 3608
+
0
-

No a co bys chtěl mít jinak? V presenteru/komponentě si zavoláš $model->getByXXX a v modelu si už můžeš klidně udělat nějaký privátní metody, který se budou předávat selection nebo s čím pracuješ…

Šaman
Člen | 2666
+
+2
-

Buď můžeš mít spoustu metod v modelu, nebo si vyrobit něco jako query-object. Anebo trochu kompromis – v modelu mít metody které doplní groupBy a where, ale orderBy a limit dostanou jako parametr.
Tady těžko říct, který přístup je lepší – u query objectu vidí presenter až moc do struktury databáze, ale zase není potřeba vyrábět samostatnou metodu pro každý pohled a grid, zvlášť pokud je takových hodně. V takovém případě už totiž zase model začíná trochu fušovat do věcí presenteru.

igor.pocta
Člen | 100
+
0
-

CZechBoY: Chtěl jsem vědět, co je správné. Zda způsob, kterým to tvořím nyní, nebo např. si z modelu převzít Context a v presenteru hrubě dopisovat omezení (where, order, group), nebo jiný návrh.

Šaman: Děkuji za tip, ten kompromis se mi zdá jako skvělý nápad.

Díky :)

newPOPE
Člen | 648
+
+2
-

@Šaman praveze QueryObject je tam na to aby Presenter do DB nevidel. A takisto odtienuje od uloziska enttit. Ak to tak je tak nieco nie je v poriadku.

@igor.pocta doporucujem tuto knizku, nie je draha a ani nie dlha https://leanpub.com/ddd-in-php. No v skratke je to o tom aky pristup chces pouzit. Predstav si Repository ktore ti tie entity spravuje (predpokladajme nejake SQLRepository ktore spravuje data v MySQL ale priklady pisem tak aby to bolo jedno co pouzijes na ukladanie entit). Implementacia by mohla vyzerat nejak takto:

class MyRepository {
  function get($id) {...} // vrati entitu podla ID
  function query(QueryObject $qb) { ... } // vrati kolekciu entit

  // a dalsie metody ako save, delete, ...
}

Ako ten QueryObject implementovat je na tebe. Skor by som siel cestou viac QueryObjectov pre dany use case. Napr. ProductFindQuery, ProductsByStatusQuery. Takto nejak by to mohlo vyzerat:

class ProductFindQuery {
  function __construct ($color, $priceFrom, $priceTo, ...) {}
}

class ProductsByStatusQuery {
  function __construct ($status) {}
}