Doplňující informace k objektu rubrika: Programování: Jiné
Mějme objekt Item a skupinu těchto objektů: ItemGroup. Případně můžeme mět ještě třetí úroveň ať je to pěkný strom. Objekt ItemGroup obsahuje nějaké atributy, plus teda pole těch Item. A Item obsahuje taky nějaké atributy.
Dále mějme šablonu/renderer který ten kořenový ItemGroup předám a ona ho nějakým způsobem vykreslí.
Teď ale nastává situace, kdy z nějakého jiného zdroje získám ke každému tomu itemu nějakou doplňující informaci. Třeba že je ten který Item enabled. A on ten typ Item tuto vlastnost nemá. Jak tyto dvě informace skloubit?
-
Tak samozřejmě bych mohl do té šablony předat dvě hodnoty. ItemGroup, a potom pole těch dodatečných vlastností klíčovaných pomocí nějakého id toho Item. Ale to se mi moc nelíbí.
-
Nebo bych mohl udělat Proxy of Item, a celej ten ItemGroup přemapovat. Což je teda jako krapet dost pracný.
- Případně ten ItemGroup včetně Item rozpustit na obyčejné beztypové struktury. Což zase, tak k čemu ty typy používám, že?
Jak byste to řešili vy? Díky za odpovědi.
Já bych asi udělal dva základní kroky.
Jednak bych sjednotil Item a ItemGroup, alespoň přes nějakého předka nebo interface (a možná přes oboje), protože ItemGroup je IMHO proste taky obyčejný Item (bude mít metodu render či něco podobného) a prostě jenom vykreslí skupinu itemů. Programu by to pak mohlo být tak trochu jedno s čím pracuje, prostě zavolá render, ostatní operace mohou být zapouzdřené (proto ta dědičnost).
A druhá věc jsou ty atributy. Implementoval bych tam (asi nejprve do předka) nějaké "skladiště atributů" tedy nějaké pole, kam se budou ukládat atributy. Na to nějaký getter (s trochou snahy do toho dostaneš i typovou kontrolu, byť to asi nebude úplně přímočaré) a setter (buď se to bude předávat přímo přes konstruktor, pokud ty atributy máš už při vzniku objektu nebo klasický setter, pokud je máš až později). Co získáš? Ke každému objektu si budeš moc dát kolik chceš atributů, budeš k nim přistupovat poměrně hezky objektově, budeš k nim přistupovat úplně stejně bez ohledu na přesný typ objektu (čili klidně přes rozhraní) a můžeš si k tomu přídělat jakoukoliv logiku, kterou chceš.
A dál? Dál si s tím můžeš hrát jak budeš chtít. Když zjistíš (a to dost možná zjistíš), že něco takového potřebuješ i někde jinde, tak si to vyrefaktoruješ do nějaké samostatné třídy a pak to budeš předávat jako závislost (nějaký AttributeStorage), nebo zjistíš, že by to bylo lepší udělat fakt přes nějakou proxy, tak si to vyrefaktoruješ do proxy atd. atp. to už pak záleží na konkrétní potřebě :-)
No snad jsem správně zachytil podstatu problému :-)
Komentáře
- harrison314 : Neporusuje to SRP, respektyve nie je to miesanie vrstiev? (aj ked to zalezi od konkretheho kotextu) — 29.9.2017
- Kit : @harrison314: SRP to neporušuje. Kolekce atributů je do Item jen zakomponována. Renderování můžeš injektovat, pokud by se ti to zdálo málo SRP. — 29.9.2017
- Taco : @arron: Moc pěkný přístup, díky! Zatím to vypadá jako favorit. Měl bych ještě dotaz k té proxy: Proxy v typových jazycích má ten význam, že má stejný typ, jako proxovaný objekt. Tudíž bych nemohl vytvořit obecnou proxy pro cokoliv (alespoň v jazycích jako Java, PHP,...). Leda tak nějaký trait. Měl jsi nějakou konkrétní představu? — 29.9.2017
- arron : @Taco: No ono hodně záleží, co tou proxy budeš chtít přesně řešit. Ideálně se Ti ta proxy bude dělat na nějakým interface a pak, pokud budeš mít jednotný interface, tak jí budeš mít stejnou pro Item i pro ItemGroup i pro nějaké třeba ItemTree (což je stejně spíš jenom další ItemGroup, že jo). Případně použít dekorátor. A nebo mít nějakou továrnu, která ty objekty vytvoří i s těmi atributy a pak nic takového možná nebudeš potřebovat :-) Ale to už záleží fakt na tom konkrétním použití, do kterého nevidím ;-) — 1.10.2017
- Anonym : Tady bych nesouhlasil, že "ItemGroup je IMHO proste taky obyčejný Item" a že by měli mít společného předka. To, že někde potřebuju stejné metody, není vůbec důvod, abych používal dědění. Tady v tom případě by se hodily interface (např. Renderable, ad.). Dědění je dobré např. ve smyslu Animal -> Dog, Cat ..., ale ne Animal -> AnimalGroup. — 2.10.2017
- arron : @Honza B.: jasně, záleží na konkrétní situaci, někdy se to hodit může, někdy ne :-) Interface je jasný, dědičnost jak kdy, s tím musím souhlasit :-) Neznám konkrétní problém, takže spíš spekuluju. — 2.10.2017
- Taco : @Honza B: Né, že by na tom záleželo, ale zrovna v tomto případě ItemGroup je prostě taky obyčejný Item, protože se s ním jako s obyčejným Itemem narába. Strká se do ItemGroup například. Je to speciální verze Itemu. Takže zrovna toto by mohl být krásný příklad dědění. Korektního. — 2.10.2017
- Anonym : @Taco: Ok, už jsem to pochopil :-) On totiž ItemGroup není skupina Itemů, ale je to Item, který *navíc* obsahuje ještě skupinu Itemů. — 2.10.2017
- Kit : @Honza B: Tuto vlastnost může mít každý Item, jen některé budou mít tu skupinu prázdnou. Tím lze docílit polymorfismu a jednotného ovládání. — 2.10.2017
- Taco : @Honza B.: Tak. Sorry, pokud jsem se nevyjádřil úplně výstižně. — 2.10.2017
Pro zobrazení všech 6 odpovědí se prosím přihlaste:
Nebo se přihlaste jménem a heslem:
Komentáře