Správné využití více managerů (Best Practise)

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

Zdravím všechny,

s PHP nedělám zas tak dlouho, celkově moc dlouho neprogramuji a teď jsem se dostal do situace kde opravdu váhám jak to teda správně je. Jen dodám že používám Kdyby\Doctrine, Kdyby\Events.

Vezmu to na příkladu, který bude snad jasný a dokážu na něm popsat kde mám problém. Mějme 2 třídy. ProductManager a WarehouseManager. ProductManager se nám stará o přidávání, editace, odstraňování produktů, fotek k produktům, atd. Nic složitého. Ale protože vím, že sklad bude mít taky svou logiku a bude lepší jej mít stranou. Takže sis jej dám do samotné třídy WarehouseManager, tam se bude naskladňovat a vyskladňovat zboží.

A teď právě přichází to, s čím si tam nejsem úplně jistej. Když budu editovat sklad produktu, musím nejdřív najít produkt (skrze ProductManager), potom ho předat do WarehouseManageru a až potom budu moci provést nějakou změnu (využívám Kdyby/Doctrine, Nette).

To znamená že je to nějaká práce navíc, než kdybych to měl prostě v ProductManageru a v něm bych naskladňoval a vyskladňoval. Snad jsem ten problém popsal srozumitelně. Jde mi o to, že si nechci ničím zbytečně přidělávat práci, tak jestli sem to jen blbě pochopil, nebo to tak prostě je.

Díky za odpovědi všem.

akadlec
Člen | 1326
+
0
-

No nevím zda tě chápu dobře, ale pokud používáš doctrine…

Pokud udržuješ nějakou historii skladu a jeho pohyby tak jendoduše si vemeš entitu produktu a předáš ji tomu WarehouseManageru s informací o pohybu, ten tuto informaci uloží do db. Entitu produktu nejspíše dostaneš pomocí ProcutManageru pokud tě dobře chápu. Na tomto postupu nevidím nic špatného.

Oli
Člen | 1215
+
0
-

Taky si nejsem uplně jistej, jestli to chápu správně. To co popisuješ zní dobře. Zkusím to shrnout jinejma slovama, jestli si rozumíme :-)

Máš sklad, který obsahuje nějaký informace (produkt, počet kusů, místo uskladnění, dobu skladování, …) a teď chceš jeden produkt vyskladnit. No tak si od productManagera vytáhneš o jaký produkt se jedná (je uplně jedno, kdo ti to řekne, ale někde tu informaci získat musíš). Když máš konkrétní produkt, tak ho předáš na sklad s informací o tom, že se má vyskladnit (snížíš počet produktů). Uměl bych si představit, že by to vypadalo zhruba nějak takhle:

$product = $productManager->fetchProduct($productId); // Vrátí instanci Product

// Vrátí instanci entity Warehouse, která je skladovaná nejdéle
$storedProduct = $warehouseManager->fetchLongestStoredProduct($product);

$storedProduct->amount -= 1;

if ($storedProduct->amount) <= 0)
{
	$warhouseManager->em->delete($storedProduct);
} else {
	$warhouseManager->em->persist($storedProduct)->flush();
}

Je to zhruba to na co jsi se ptal?

Pavel Kravčík
Člen | 1196
+
0
-

Podle mě mu spíš jde o to „probublávání“ mezi více modely/managery.

Asi to vypadá na hledání best-practise návrhu aplikace.

Azathoth
Člen | 495
+
0
-

Také si nejsem jistý, jestli jsem to správně pochopil, ale podle mne by nebylo špatné použít eventy, že bys v product manageru vyvolal vyskladňovací nebo naskladňovací událost, kam bys poslal ten daný produkt a WarehouseManager by měl listener, který by se na tu událost napojil a provedl to, co je zapotřebí.

Martin Vaněk
Člen | 10
+
0
-

Zdravím, děkuju za odpovědi, ale asi jsem se špatně vyjádřil.

Myslel jsem to tak, jak píše @kzk_cz. Jde mi o návrh, kdy chci spojit více tříd, které obsluhují věci kolem produktů. Pořád tápám jestli to dávat do jedné třídy, či do více. Vím že to tak úplně k Nette nepatří, ale když už tam jede Kdyby\Events, tak sem myslel že by to šlo nějak více zkloubit, jak píše @Azathoth.

Proto sem hledal nějaké už hotové řešení na Githubu, kde by byl nějaký nástřel. Potom mě napadlo zeptat se místních odborníků.

Azathoth
Člen | 495
+
+2
-

Doporučuji se podívat na https://www.youtube.com/watch?…
třeba ti to pomůže. Já mám například třídu UserCreator, která registruje nové uživatele a ta vyvolá událost při registraci nového uživatele a toho uživatele předá jako argument. Třída MessageSender naslouchá na tenhle event a pošle danému uživateli registrační e-mail. Takže UserCreator vůbec o MessageSenderovi nemusí vědět.
Myslím si, že eventy jsou na tohle nejelegantnější.

Martin Vaněk
Člen | 10
+
+1
-

Super, děkuji za odpovědi. Takže nebude technicky špatně, když budu mít ProductManager, v něm budu mít funkci na změnu počtu kusů skladem, na tuto funkci navážu listener a třeba WarehouseManager bude na tento listener naslouchat a při zavolání funkce v ProductManageru to už zpracuje WarehouseManager?