Invalidace objetku – onChange?

Fires
Člen | 97
+
0
-

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í:

  1. volat v každém setteru : $this->invalidate() – podle mě hrozná blbost
  2. 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
+
0
-

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 :)

CZechBoY
Člen | 3608
+
0
-

Tak muzes si udelat BaseObject, kterej v konstruktoru vytvori uuid identifikator…

Martk
Člen | 661
+
0
-

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.