Diskuze: Výhody objektů
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Tvůrce

Zobrazeno 50 zpráv z 112.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.
Já mám hackrovské znalosti jen hodně okrajově, takže nevím, ale nemyslím si, že by to byla tak závažná díra.
Zvlášť, když používání statiky v databázi bylo do nedávna normální.
To bezpečnostní riziko je podobné, jako kdybys měl všechny atributy objektu public. Kdyby tam žádné riziko nebylo, nikdo by se nenamáhal používat private a skrývat implementaci všude, kde to jen jde.
Pokud na projektu pracuje víc vývojářů, riziko je hlavně uvnitř. Stačí aby jeden z nich udělal v aplikaci jednu bezpečnostní díru. Útočník pak má k dispozici celý systém bez omezení. Proto se ta omezení dělají.
Do konfigurace operačního systému je přece také blokován zápis, aby sis v něm náhodou něco neponičil. Spuštěné programy si také nemohou vzájemně přepisovat data v operační paměti, dokonce je ani nemohou číst.
Skrývání implementace je hlavně z důvodu přehlednosti, přes reflexi ti zavolám privátní metodu jako nic, takže to není žádná ochrana.
Závažná určitě není. To by se to rychle rozšířilo. Ale hackeři se dostanou i pomocí těch nejmenších skulinek.
Neříkám, že to není riziko. Je to ale riziko zevnitř, které se při použití statických tříd musí podstoupit. Není to ale vhodné použití u citlivých dat, zvlášť, když na tom pracuje více programátorů.
(Ještě jen tak mimochodem: Kit: že zrovna ty se zajímáš o práci více
vývojářů. , sdraco: fajn
avatar.
Problém je hlavně v tom, že používání statiky strašně svádí k substituci za globální proměnné. A ty vedou do pekel. Zpočátku to vypadá jako velmi výhodné, ale jak projekt roste, tak se z výhody časem stane nevýhoda. Omezuje se tím znovupoužitelnost tříd, protože pokud je třída statická, nemůžeš ji použít ke dvěma různým účelům.
Právě od toho statika existuje. Když potřebuješ jen jednu instanci. Přesně proto byla statika vytvořená.
Tak ona není jen k tomu, statický můžeš mít jen jeden atribut, jedná se o data, co jsou společná všem instancím. Nejjednodušší ukázka je konstanta, ta je přeci také třídní.
Co třeba taková třída Math v Javě? Budeš si předávat všude instanci
abys udělal mocninu?
Math v Javě si žádná data neukládá. Je to jen kontejner na funkce, jejichž výstup je závislý pouze na vstupních datech, ale vůbec není závislý na nějakém vnitřním stavu třídy. Pokud by v takové třídě existoval jen jeden statický přepínač, třeba mezi stupni a radiány, byl by to vážný problém.
Ano. U Math vidím smysl. Pokud bych však měl mít možnost přepínat mezi stupni a radiány, dělal bych instance a konstruktoru bych předával, zda chci stupně nebo radiány. Takovou instanci bych pak musel předávat.
Naštěstí tvůrci Math takto šílení nebyli a udělali ji z tohoto pohledu správně, tedy staticky a bez vnitřních stavů.
Takže pokud si chceš udělat třeba vlastní statickou třídu Str, která bude pracovat se stringy přes funkce mb_* a nebude mít žádné vnitřní stavy, nebudu mít nic proti tomu. I když ... jeden vnitřní stav asi mít bude a bez něho by to bylo stěží použitelné. Můžeš ho však udělat jako konstantu.
Nemůže být VŽDY jen jedna instance, někdy prostě potřebuješ, aby se další instance nevytvořili.
Pardon:
Myslíš Singleton? Ten přece není potřebný. Ke každému rozhraní mám nejméně dvě instance. Tam bych se Singletonem nepochodil.
Proč bych si nemohl vytvořit další instanci nějaké třídy? Když potřebuji otevřít další soubor nebo databázi, tak nebudu kvůli tomu dělat další třídu.
EDIT: Chvilku mi to trvalo, ale pochopil jsem, co jsi myslel.
Při testování si s jednou instancí nevystačíš. Právě testování tě odnaučí dělat statické třídy s vnitřními stavy.
Občas mi použití singleton/statiky přijde mnohem jednodušší a přehlednější než si všechno předávat celou hierarchií objektů...
Když mám třeba hru, kde mám nějaký TextureManager, který má u sebe všechny načtené textury (takže vím, že nemá smysl vytvářet jeho další instanci) a mám kompozici tříd třeba podobnou této:
Program-Game-Map-GameObjectList-GameObject-Animation-Texture
nebo
Program-Game-Map-MapFields-MapField-Animation-Texture
Tak dám přednost vytvoření této statické třídy TextureManager s vnitřními stavy, než abych musel všude předávat (a třeba i ukládat) referenci na TextureManager.
A pokud se k tomu přidají ještě třeba FontManager, SoundManager, Pozice kurzoru myši, informace o rozlišení obrazovky (kvůli vykreslení mapy, GUI) apod., tak mi to nabobtná tak, že budu v kontruktoru všech objektů předávat milion parametrů...
Pokud to budeš dělat objektově, tak těch předávaných parametrů je jen skutečné minimum. K popsané situaci vůbec nedojde.
Taky mě jeho odpovědi na objektivitu matou.
Tohle bych řešil přes strukturu kam bych dal všechna potřebná data v podobě objektů těchto tříd a pak předával jenom instanci té struktury. Parametr by byl tudíž jenom jeden. Ale souhlasím, že u záležitostí jako jsou tyto je asi statika přehlednější a snadněji se to pak používá.
No, asi by to šlo, ale taky si to musíš posílat celou hierarchií, což
je otravné, ale jeden parametr už by se snad dal překousnout .
Nebo by se to dalo udělat tak, že by sis udělal statickou třídu, která by měla odkazy na instance všech těch objektů (takže ty objekty jako TextureManager apod. by statické nebyly), nějak takto:
public static class ResourcesAndSimilarStaticUglies
{
public static TextureManager TextureManager;
public static SoundManager SoundManager;
public static FontManager FontManager;
public static ScreenInfo ScreenInfo;
public static MouseState MouseState;
public static KeyboardState KeyboardState;
}
Ještě by bylo možná ideální udělat Manager jako šablonu (generickou
třídu) a dodávat typ (Manager<Animation>, Manager<Font>...)
rozdíly v rozhraní a datových položkách bych vyřešil ve specifikacích,
což v C# asi neuděláš, tam bys mohl oddědit pak jednotlivé Managery.
Uplně ideální by bylo kdyby tam žádné rozdíly nebyly
Nevšiml jsem si toho. Umí ten tvůj TextureManager ty textury i vykreslovat? Umí ten SoundManager přehrávat zvuky? Pak se totiž ty managery nemusí prohrabávat žádným stromem, protože data mají lokálně u sebe.
Objekt Game, objekt Map, objekt Texture... tak jak je to tedy objektově,
když ne takhle?
TextureManager nekreslí, ten jen udržuje u sebe seznam textur.
Vytvoříš nový GameObject, třeba tank -> načte si z manažeru
texturu.
Ne, GameObject má metodu Draw(), která podle jeho pozice a fáze animace vykreslí správnou texturu na správné místo.
Vytvoříš třeba objekt tank, konstruktoru předáš objekt-texturu, která se umí vykreslit a objekt-zvuk, který se umí přehrát. Tank pak v sobě má atributy-objekty, které umí vykreslit svou texturu a přehrát svůj zvuk. V továrně si tak můžeš vyrobit třeba transportér se zvukem stíhačky, při upgrade tanku mu třeba jen vyměníš texturu a samozřejmě schopnosti.
Já to dělám stejně jako Luboš Běhounek Satik a přijde mi to přehledné . Do managerů si načtu všechny
potřebné texturu a poté různé GameObjecty si načítájí texturu jakou
chtějí.
Stejně musíš mít ty obrázky v něčem statickém, aby fungoval lazy loading. Texturu nepředáváš v konstruktoru, ale tvoří si jí ten objekt, je to jeho textura. Co se mi osvědčuje je vytvořit si závislosti v jednom kontejneru a ten předávat, okoukal jsme to z XNA a funguje to skvěle.
Co se týká možností, neumí OOP nic navíc než assembler nebo normální programování pomocí podprogramů, ale má spoustu výhod hlavně pro větší projekty:
Samozřejmě jsou i nevýhody - OOP programy jsou mírně pomalejší kvůli vyšší režii, navíc pro malé projekty je zbytečně složité a je často vhodnější použít jednodušší přístup, zkus např. porovnat hello world v Pascalu a v Javě. Je to prostě určitý přístup, který je vhodný pro spoustu věcí, ale pro specifické problémy můžou existovat i lepší řešení.
To je hezké, skoro jak z učebnice. A teď to zkus aplikovat na statický objekt Texture. Mně se to nepovedlo.
Objektově psané programy nemusí být nutně pomalejší. Mohou být i rychlejší.
Nemohou být rychlejší už z principu. OOP s sebou nese spoustu režie navíc.
Hmm, to slýchám poměrně často. Zejména od těch, kteří OOP neovládají.
Možná by tedy bylo lepší se zeptat těch, kteří OOP umí.
To je celkem relativní, záleží na tom, co bereš jako centrum vztažné
soustavy
Na tom nic logického není.
Země je placatá, nesou ji čtyři sloni,
kteří stojí na zádech obrovské želvy.
To ví přece každý.
Gratuluji, první komentář, který nám něco dal, napsal TomBen
Tak pokud se nebavíme o matematice, nic neplatí na 100 %. Ano, program napsaný objektově může být teoreticky rychlejší, ale většinou není, např. kvůli virtuálním metodám. Myslím, že když se někdo ptá, jaké jsou výhody OOP, ocení spíš obecnou odpověď, klidně přetlumočenou z učebnice, radši než nějaké speciality, kterými se může zabývat profesionál, který OOP ovládá a používá na trochu jiné úrovni.
Vadí mi jedna věc: Když někdo napíše, že malou nevýhodou OOP je, že je o něco pomalejší, tak začátečník si z toho obvykle vezme jen "OOP je pomalejší" a stane se to pro něj argumentem, že je to šmejd. Přitom výkonové rozdíly jsou naprosto nepodstatné a jsou oběma směry.
Uznávám, že když se OOP použije nešikovně, což je velmi častý případ, jsou programy pomalejší. Určitě to není kvůli virtuálním metodám, ty to naopak zrychlují.
Jak konkrétně virtuální metoda program zrychlí? Při jejím volání se vždy musí udělat minimálně o jeden krok více.
Virtuální metody se píší jinak, bývají jednodušší a tím i rychlejší.
Moje virtuální metoda většinou vypadá tak, že volá stejnou metodu některého z předků a k tomu dělá něco navíc. Mám pocit, že tím je spíš naopak o něco pomalejší.
Aha, většinou ji zcela překrývám a specializuji. Proto se mi tím zjednoduší.
Zobrazeno 50 zpráv z 112.