Volanie funkcie z ineho repository
- gogy27
- Člen | 6
Zdravím,
mám začiatočnícky problém, keďže neviem na 100% ako to v Nette
funguje.
Jednoduchý problém: Mám nejaký repository, v ktorom pracujem
s kategóriami a v ňom nech mám funkciu, ktorá tieto kategórie
vymazuje:
<?php
class CategoriesRepository extends Repository
{
/** @param Nette\Database\Table\IRow */
public function delete($category) {
if ($category) {
$category->delete();
$photos = $this->getPhotos($category->id);
// Tu chcem zavolat funckiu delete, ktora je v repositori photos
// Nieco na styl ako je v presneteri:
// $photosRepository = $this->context->photosRepository
// foreach ($photos as $photo) {
// $photosRepository->delete($photo->id);
// }
}
}
}
?>
Ďakujem za nakopnutie.
Editoval gogy27 (10. 2. 2014 1:57)
- Etch
- Člen | 403
No můžeš si tam to repository samozřejmě normálně injectnout, ale otázka zní, jestli je to vůbec dobře.
Ty vlastně chceš docílit toho, aby CategoriesRepository
fušovalo do práce PhotosRepository
a osobně si nemyslím, že je
to příliš dobré. Problém totiž je, že ve chvíli, kdy to uděláš tak
jak teď chceš, už daná metoda CategoriesRepository::delete()
nedělá to, co by se od ní na první pohled očekávalo.
Pokud někde zavolám:
$categoriesRepository->delete($category);
tak předpokládám, že to udělá jen to o co jsem opravdu požádal, tedy smaže se kategorie. Jenže ono to tak není, protože repository „zcela bez mého vědomí“ začne mazat i fotky z dané kategorie, což navenek nikde nemám šanci poznat. Vznikne tím i další „problém“, že ne vždy musíš chtít dané fotky opravdu smazat. Například chceš jen smazat kategorii a kategorii u fotek nastavit na NULL nebo chceš udělat merge kategorií.
Pro takovéhle věci bych si spíše udělal fasádu
a až tam
to řešil, protože je pak jasně vidět, co se opravdu stane a eliminuje to
WTF faktor.
class PhotosService {
private $categoriesRepository;
private $photosRepository;
public function __construct(CategoriesRepository $categoriesRepository, PhotosRepository $photosRepository){
list($this->categoriesRepository, $this->photosRepository) = func_get_args();
}
public function deleteCategory($category){
$this->photosRepository->mergeCategories($category, NULL);
$this->categoriesRepository->delete($category);
}
public function deleteCategoryAndPhotos($category){
$this->photosRepository->deleteByCategory($category);
$this->categoriesRepository->delete($category);
}
}
Pokud teď zavolám:
$photosService->deleteCategoryAndPhotos($category);
// nebo
$photosService->deleteCategory($category);
Tak to udělá přesně to co by člověk očekával. První prostě smaže
kategorii včetně fotek. Druhé nastaví u fotek z dané kategorie kategorii
na NULL a následně kategorii smaže. Je ovšem hned na první pohled vidět,
co se bude v kterém případě opravdu dít a není to schované pod
„nicneříkajícím“
$categoriesRepository->delete($category);
.
Editoval Etch (10. 2. 2014 3:35)
- Pavel Macháň
- Člen | 282
Etch napsal(a):
.....
class PhotosService { private $categoriesRepository; private $photosRepository; public function __construct(CategoriesRepository $categoriesRepository, PhotosRepository $photosRepository){ list($this->categoriesRepository, $this->photosRepository) = func_get_args(); } .....
Tak to udělá přesně to co by člověk očekával. První prostě smaže kategorii včetně fotek. Druhé nastaví u fotek z dané kategorie kategorii na NULL a následně kategorii smaže. Je ovšem hned na první pohled vidět, co se bude v kterém případě opravdu dít a není to schované pod „nicneříkajícím“
$categoriesRepository->delete($category);
.
Proč toto? To mě nepřijde jako moc přehlednej (a čistej) zápis. Vypsat to po jednom nezabere tolik času.
list($this->categoriesRepository, $this->photosRepository) = func_get_args();
- Etch
- Člen | 403
EIFEL napsal(a):
Proč toto? To mě nepřijde jako moc přehlednej (a čistej) zápis. Vypsat to po jednom nezabere tolik času.
list($this->categoriesRepository, $this->photosRepository) = func_get_args();
Zeptal bych se opačně. Proč ne?? V čem přesně ti tento zápis nepřijde „čistý“ a to konkrétně v tomto případě, kdy jsou všechny parametry konstruktoru povinné??
Přehlednost je pak myslím čistě subjektivní věc. Stejně jako nikomu
nenutím ternární operátor, tak nikomu nenutím ani tuto konstrukci pomocí
list
a func_get_args()
. Každý si může ten
konstruktor přepsat do podoby, jak mu vyhovuje.