Autor Zpráva
AM_
Profil
Zdravím,
řeším už poněkolikáté objektový problém. Mám nějakou nadřazenou třídu, řekněme "class tabulka", která obsahuje array nějakých dalších objektů, řekněme dědiců abstraktní třídy "class bunka", které reprezentují jednotlivé buňky tabulky a mají např. společnou funkci bunka->vypis_obsah(); která je volána třídou tabulka při výpisu celé tabulky. Nyní budu chtít udělat takovou rozšiřující třídu ke třídě buňka, která bude řekněme vypisovat spojené údaje z prvních dvou buňek v tabulce. Pro názornost nějak takto:
class bunkaA extends bunka{
  public function vypis_obsah(){
    return "a";
  }
}
class bunkaB extends bunka{
  public function vypis_obsah(){
    return "b";
  }
}
class bunkaAB extends bunka{
  public $master_table;
  public function vypis_obsah(){
    return $master_table->bunky[0]->vypis_obsah().$master_table->bunky[0]->vypis_obsah();
  }
}
$bunka1 = new bunkaA;
$bunka2 = new bunkaB;
$bunka3 = new bunkaAB;
$bunka3->master_table = &$tabulka;
$tabulka->bunky = array($bunka1, $bunka2, $bunka3);


Je toto řešení - předat odkaz na nadřazený objekt onomu podřazenému objektu - z hlediska efektivity OOP správné? Nebo jak se to má dělat? Principy OOP relativně znám, nyní se učím je nějak inteligentně aplikovat v praxi.
Joker
Profil
Podle mě by tohle neměla řešit metoda třídy buňka, ale metoda třídy té nadřazené tabulky.
blizz_boz
Profil
nepochopil som o co ide v tvojom priklade ale k nadradenemu objektu sa pristupuj cez keyword "parent" pricom sa pouziva staticke volanie "::"
TomášK
Profil
Tohle není rozumné použití OOP.

Co je ok?
Mít třídu Bunka a od ni dedit dalsi tridy - dle druhu buňky. Kdyby to mělo jenom vypisovat "a" nebo "b", není to dobře, protože na tohle by měla být jedna třída a vlastnost té třídy by byl řetězec, který vypisuje. Rozumné použití by bylo, kdy se jedna buňka vypisovala jako text a jiná třeba jako obrázek. Nicméně chápu, že je to jen příklad.

Co není ok?
Dělat třídu, která vypisuje první dvě buňky z tabulky, je špatný návrh. Zlo. Pro vypsání prvních dvou buněk tabulky bys měl udělat funkci ve třídě tabulka, která to bude dělat. Dělat na to třídu je chyba - nic tam nedává rozumný smysl: jako jeden odstrašující příklad za všechny uvedu situaci, kdy bunkaAB bude jedna z prvních dvou buněk tabulky - výpis se zacyklí.

Objekty jsou od toho, aby ti práci zjednodušovali, ale ne od toho, abys je musel nutně cpát všude za každou cenu ;-)
AM_
Profil
TomášK
Jasně, snažil jsem se na maximální možnou míru zjednodušit problém, abych vyjádřil pointu. Samozřejmě každá odvozená třída vypisuje jiný typ dat, jen tady pro jednoduchost jsem napsal dva odlišné řetězce. Ve skutečnosti k datům tabulky přistupuji po řádcích a celý model je mnohem složitější, takže to, co popisuješ, že není ok, vzniká až v tomhle zjednodušeném příkladu. Ve výsledku právě každá z položek bude mít odlišné vlastnosti a je potřeba návrh udělat tak, aby byly programovatelné úplně nové typy položek, proto mají položky různé třídy odvozené od jedné základní.

Pointou dotazu bylo především to, jestli je OK takto přistupovat k nějaké instanci nadřazeného objektu, který spravuje skupinu podřazených objektů. Připadá mi to totiž trošku kostrbaté, ale to je možná jenom pocit, protože ať o tom přemýšlím jakkoli, tak to asi lépe řešit nejde, protože vlastně žádný programový vztah umožňující přístup z instance objektu, který je členem instance nadřazeného objektu, prostě není.

blizz_boz
Statické řešení je nepoužitelné, co když budu mít souběžně více tabulek?
Asdef
Profil
Nevim jestli to chápu správně. parent:: Odkazuje na bázovou třídu
blizz_boz
Profil
Statické řešení je nepoužitelné, co když budu mít souběžně více tabulek?

Nevim jestli to chápu správně. parent:: Odkazuje na bázovou třídu

aj ja to tak tiez chapem, proste parent:: je nieco ako keyword base v C# alebo inherited v Delphi ja to tak aj v PHP pouzivam. akurat k base sa pristupije cez bodku co je equivalent "->" v php, teda dynamicke volanie. zatial s tym nebol problem, PHP ma zaujima len okrajovo...
kto tomu rozumie lepsie mohol by to vysvetlit.
TomášK
Profil
AM_
Přistupovat k instanci nadřazeného objektu je podle mě ok. Setkal jsem se s tím před pár dny v grafické knihovně Qt - třída QObject má konstruktor QObject ( QObject * parent = 0 ), od třídy QObjekt dědí všechny ostatní grafické prvky. Tedy odkaz na rodiče si objekt pamatuje, k čemu se přesně používá, nevím, ale dokážu si představit jeho rozumné použití - např. když někdo klikne na buňku tabulky pravým tlačítkem, tak se ta buňka zeptá rodiče, jaké kontextové menu má vykreslit.

Argument 'je to dobré, protože to používá někdo jiný' není úplně ubíjející, ale myslím, že ta knihovna je dost používaná na to, aby tam měly nějaké vyložené blbosti :)
AM_
Profil
Nejde o odkaz na nadřazenou třídu v hierarchii tříd, je blbost, aby buňka dědila třídu tabulky. Jde o jednu třídu, která jakoby spravuje skupinu jiných tříd (třída tabulky spravuje skupinu buněk, které jsou reprezentovány jinou třídou). Žádná spojka směrem z buňky do celé tabulky z hlediska principu OOP neexistuje, buňce se podle mě musí explicitně "říci", ke které instanci tabulky je přiřazená.
Joker
Profil
AM_
Žádná spojka směrem z buňky do celé tabulky z hlediska principu OOP neexistuje, buňce se podle mě musí explicitně "říci", ke které instanci tabulky je přiřazená.
Přesně tak.

Ale jak říkám, většinou je rozumnější to řešit přímo na třídě tabulka.
AM_
Profil
Joker
Jasně, to mě taky napadlo, ale když budu potřebovat napsat takovou třídu buňky, která např. textový obsah buňky vytvoří na základě jiných hodnot v daném řádku tabulky, přijde mi zpětný odkaz na tabulku jako jediné řešení.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: