Invalidace objetku – onChange?
- Fires
- Člen | 97
Zdravím,
neřešil jste někdo invalidaci objektu při zavolání nějakého setteru ?
Mám objekt reprezentující záznam v databází. Tento objekt si v sobě nese proměnou „valid“. Kterou bych potřeboval na základě zavolání jakéhokoliv setteru změnit na false. Používám SmartObject.
Možná řešení:
- volat v každém setteru : $this->invalidate() – podle mě hrozná blbost
- přepasat magickou metodu __set() – magii nemám moc rád a nechci aby se to bilo s SmartObject.
Můžete mě někdo kopnout aspoň správným směrem ? Díky.
- Milo
- Nette Core | 1283
Na to asi žádná jediná správná odpověď neexistuje.
Pokud jsou všechny settery magické, tedy přes __set()
,
vlastní implementace není špatná volba. Dá se vyřešit traitou a z ní
případně volat SmartObject
implementaci. První problém se ale
ukáže ve chvíli, kdy ne vše se nastavuje přes __set()
.
Detekce změny se také nemusí řešit ihned. Po vytvoření entity lze
hodnoty properties uložit a na požádání je porovnat s aktuálními
hodnotami. Implementace se zase dá vyřešit traitou s metodami například
saveState()
a hasStateDiffer()
.
V tomhle případě problém nastane, když se má entita serializovat. Jsou s tím akorát potíže.
Možná by si tedy entita stav o své změně vůbec nemusela uchovávat,
mohl by to dělat repozitář, když entitu vytváří. Nabízel by potom metodu
hasEntityChanged(Entity $x): bool
, nebo
getEntityDiff(Entity $x): array
. Jenže v tomhle případě zase
musí být entita jednoznačně identifikovatelná a musí být z databáze
načtena vždy jen jedna s touto identitou.
Vše výše uvedené jsem vyzkoušel a ani s jedním řešením nejsem spokojený. V PHP mi chybí nějaký unikátní identifikátor objektů.
Každopádně, také uvítám jakoukoliv erudovanou radu :)
- Martk
- Člen | 661
Další možnost, ale stále má nějaké nevýhody:
Vytvořil bych smart proxy a k tomu vlastní hydrataci. Bude to jednoduchý objekt, který v podstatě nic neumí.
class ArticleProxy {
/** @var callable[] */
public $onChange = [];
public function __construct(Article $article) {
$this->article = $article;
}
// magické metody __get, __set, __call apod. které volají právě article metody, proměnné apod. a také volají onChange, případně nastavují příznaky, cokoliv budeš chtít
}
Vlastní proxy hydratace bude jednoduchá, protože bude dědit od ObjectHydrator (data na entitu) a přetížíš funkci hydrateRowData a tam vytvoříš svoje proxy.