.[ ČeskéHry.cz ].
Singleton::jak to s ním vlastně je?
Jdi na stránku 1, 2, 3, 4  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 30. říjen 2008, 20:09:00    Předmět: Singleton::jak to s ním vlastně je? Odpovědět s citátem

Zdravím vás,
stále pracuji na svém projektu, ale při novém návrhu jádra hry jsem trochu popřemýšlel...
(Problém popíši třeba na manageru textur)
Doposud jsem objekt, který jsem potřeboval pro všechny ostatní objekty, vytvořil jako globální... sice to funguje tak jak má, ale co když náhodou vytvořím novou instanci manageru textur, tak vlastně textury, které spravuje ten první nebude vidět do textur, které spravuje druhý...textury se tedy mohou nahrát vícekrát...což znamená, že třída manažeru nemá vlastně žádný smysl...
No a když sem pátral jak udělat to, aby v celém systému byl jenom jeden manažér textur, tak jsem narazil na singleton...
Implementace snadná, ale vrtá mi hlavou několik věcí...(ptám se protože jste přeci jenom zkušenější a určitě mi rádi odpovíte... Wink )

Je výhodné singletony využívat? Nebo je ještě nějaká jiná alternativa?
Je správné použít singleton, když vím, že instance třídy bude opravdu jenom jedna...?

Funguje to jako hezky, ale vygooglil jsem také spoustu negativisticky pojetých článků...ale stále mi nějak unikají nějvětší problémy na které bych si měl dát pozor...

Snad jste mě pochopili...
Abych pravdu řekl, nechci nějaké odkazy, chtěl bych znát váš názor...tak ho sem napište... Very Happy
Díky za odpovědi...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 30. říjen 2008, 20:23:09    Předmět: Odpovědět s citátem

Jedinej problém se singletonem je v tom, že když se pak rozhodneš, že bys vlastně potřeboval víc instancí, budeš muset přepsat jeho používání v celým kódu (tzn. tak 1000 míst Smile.

Druhej problém je možná ten s globálními daty, protože to přesně singleton vlastně je. Problém s globálními daty je ten, že zvyšujou složitost kódu, protože ten pak není ovlivněn jen tím, co mu přišlo za parametry a případně daty ve třídě, ve které se metoda nachází, ale také těmi globálními daty. To znamená, že když ty globální data na jednom místě změníš, může to mít vliv na jiný kus kódu (typicky takový vliv, že to přestane fungovat).

Takže singleton - proč ne, ale je třeba ho použít správně a podle mě se zrovna na správce textur hodí.

EDIT: Další problém singletonu je v tom, že ho někdy lidi používaj tam, kde by se používat neměl a používají ho proto, že jsou líní předávat si ukazatel na daný objekt přes delší hiearchii volání. Ono napsat MujSingleton::Instance->metoda() je o dost jednodušší.
_________________
Mám strach
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Augi



Založen: 28. 07. 2007
Příspěvky: 782
Bydliště: Čerčany

PříspěvekZaslal: 30. říjen 2008, 20:37:04    Předmět: Odpovědět s citátem

Já bych raději singleton nepoužil. Místo toho bych si všude strkal odkazy na všechny potřebné objekty. Sice to bude víc práce, ale výkonová ztráta bude nulová a přehlednost a příp. budoucí úprava kódu jednodušší...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
MD



Založen: 29. 07. 2007
Příspěvky: 437
Bydliště: Praha

PříspěvekZaslal: 30. říjen 2008, 21:43:45    Předmět: Odpovědět s citátem

A uz je to tu zas! : )
No ja si vyzkousel to meneni na 1000 mistech, takze vim, jak to da zabrat Wink

Jinak bych nebyl absolutne proti singletonum, svoje opodstatneni maji. Jen si musis poradne promyslet zda NIKDY (ani za 10 let) nebudes chtit vytvorit dve konkurencne bezici instance. Takze treba:
Renderer - hmm asi neni singleton, co kdyz budu chtit vykreslovat dve veci do ruznych oken (zpetne zrcatko)?
Hra - taky ne - mit moznost pustit dve hry najednou je celkem fajn - treba v editoru levelu, pri navrhu, kdyz dve hry chci pustit proti sobe, simulace hry v jine hre..
Manager textur - no asi jo, textury jsou na disku jen jednou, jsou to konstantni objekty(!) a chci je sdilet mezi vsemi komponentami

Jinak dalsi velky problem globalnich dat je multithreading. Kdyz ma kazde vlakno sve objeklty a sva data na stacku je to v pohode. Ale pokud vlakna zbesile sahaji na globalni data (singletony) jsi v brynde Wink
_________________
- play with objects - www.krkal.org -
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 30. říjen 2008, 22:05:20    Předmět: Odpovědět s citátem

MD napsal:
A uz je to tu zas! : )


je - ale nedari se mi najit to vlakno kde jsme to resili minule :/ - jinak bych to davno zamcel
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
OndraSej



Založen: 28. 07. 2007
Příspěvky: 767
Bydliště: Brandýs nad Labem

PříspěvekZaslal: 30. říjen 2008, 22:07:25    Předmět: Odpovědět s citátem

Jeste je se singletony drobny problem s poradim vytvareni a ruseni.

A pak je tu trochu problem, ze kdyz se vytahne vec jako sprava textur ven z rendereru/engine (a napr. bude sdilena mezi vice enginy), tak tim hrozi naruseni zapouzdreni toho engine a je nutne nejak rozumne resit konflikty pri pristupu.

Pokud jde o singletony, tak si myslim, ze jejich vyuziti ma smysl hlavne v situacich, kdy (1) potrebujes vynutit jedinecnost objektu a soucasne (2) z nejakeho praktickeho duvodu (napr. kvuli nejakemu cizimu API) potrebujes mit tu jedinecnou zalezitost reprezentovanou jako objekt.

Jinak si myslim, ze pri pouzivani libovolneho navrhoveho vzoru je potreba predevsim pouzivat zdravy rozum a pouzivat vzory v situacich, ktere je vyzaduji. Ne umele vytvaret situace, ktere by mohly vyuzit nejaky vzor.
_________________
http://trionteam.net
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 31. říjen 2008, 03:31:19    Předmět: Odpovědět s citátem

Myslím si, že singletony za normálních okolností nejsou vůbec potřeba, vždycky se to dá udělat jinak. Co vím, tak nějaké C API mívají jeden jediný globální context, tam se to může hodit, ale je lepší to pěkně zakrýt, aby to nebylo poznat.

MD napsal:
Manager textur - no asi jo, textury jsou na disku jen jednou, jsou to konstantni objekty(!) a chci je sdilet mezi vsemi komponentami

Taky ne. Manažer textur vytvoříš jednou a každému objektu ho normálně předáš. Může se objevit požadavek do toho manažeru něco přidat a potom ti nic nebude bránit ho vytvořit podruhé...
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
]semo[



Založen: 29. 07. 2007
Příspěvky: 1526
Bydliště: Telč

PříspěvekZaslal: 31. říjen 2008, 10:46:14    Předmět: Odpovědět s citátem

eosie: nechápu, proč podruhé?

Singletony jsou dobrý, pro ty managery dat to rozhodně doporučuju. Nesporná výhoda, kterou asi nikdo nezmínil, je že se na singleton můžeš spolehnout. Tím myslím, že vždycky tu je, nemusíš testovat, jestli ti náhodou někde v parametru nepřišel NULL, a podobně. Samozřejmě hnidopichové řeknou, že to záleží, kde ten singleton vytváříš a že nemám pravdu, ale v praxi to je jak říkám.
Ovšemže, existuje-li jen teoretická možnost použití oné konkrétní třídy ve více instancích, neměl by se singleton používat, protože si tím uzavřeš možné cesty.
_________________
Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 31. říjen 2008, 12:33:12    Předmět: Odpovědět s citátem

]semo[ napsal:
eosie: nechápu, proč podruhé?

Když chceš mít více instancí enginu pro experimentální účely třeba. Wink Já je teda taky dřív používal, ale časem jsem si uvědomil, že stejně není o co stát. Nic navíc to nepřináší a komplikuje to pozdější úpravy (zažil jsem si to sám). Je to prostě prvek strukturovaného programování, který se nějak dostal do objektového a nemá tam co dělat. Jinak pokud kombinujete strukturované programování a objektové, pak je celkem přirozené používat globální proměnné (což singleton je). Čistý objektový kód je nepotřebuje.

Jinak Augi to dobře vystihl.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 31. říjen 2008, 12:55:09    Předmět: Odpovědět s citátem

Teď jsem trochu zmatený...
Ale začínám si to už uvědomovat...když vytvořím singleton, tak je to vlastně jako kdybych vytvořil globální proměnné a globální funkce (a jsme ve strukturovaném programování) a jen odchytával, jestli jsem náhodou neudělal něco víckrát, než by se mělo...jen to mám trochu sbalené...

Jaké správné řešení tedy navrhujete aby to bylo podle pravidel OOP?
Možná že bych uvítal kousek nějakého kódu...možná ne jen já...
Díky...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
rezna



Založen: 27. 07. 2007
Příspěvky: 2156

PříspěvekZaslal: 31. říjen 2008, 13:18:48    Předmět: Odpovědět s citátem

jakeho kodu? - proste si vsechno co je potreba predavej pekne v argumentu vsem funkcim - tak se to proste dela v OOP. singleton je moznost jak z tohoto vybocit - ale jak uz bylo zmineno muze vest do pekel.

pekny neherni priklad je ze spousta programatoru pouziva singleton na pristup k DB. jejich aplikace prece pracuje s jednou DB ze. jaky to omyl kdyz prijde zakaznik ktery dvoje data a potrebuje s nimi pracovat v jedne aplikaci.

sigleton je proste ve sve podstate globalni promenna ktera zarucuje ze je prave jedna

a co se tyce OOP cistoty na to se dost casto nehraje - jde o to aby program fungoval rozumne a tobe se dobre psalo. to s cistotou nema nic spolecneho.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
]semo[



Založen: 29. 07. 2007
Příspěvky: 1526
Bydliště: Telč

PříspěvekZaslal: 31. říjen 2008, 13:19:55    Předmět: Odpovědět s citátem

Navrhuju používat Singletony, rozhodně jo. Jsou dva extrémy, jeden je Eosie (uplně bez singletonů) a druhý třeba engine Ogre, kde je singleton uplně na všechno. Zlatá střední cesta. Stejně nikdy nebudeš dělat více instancí enginu ani pro experimentální účely. Počítat při návrhu a programování s takovouhle věcí je celkem nepříjemný.

EDIT:
Naopak předávat všechno parametrama může vést do pekel. Máš třeba nějakou abstraktní bázovou třídu. Z ní je odvozená další třída, která v implementaci těch abstraktních metod chce přistupovat k nějakým "globálním službám" což, krásně zpřístupní singleton. Pokud je nepoužiješ, musíš upravit i tu bázovou abstraktní třídu - což mi příde jako mnohem větší prasečina. Jediný další řešení je mít nějakou globální funkci, která vrátí dejmetomu TextureManager[i], chceš-li jich mít víc. Pak už ale musíš vždy počítat s vícero instancema a tak dál...
_________________
Kdo jede na tygru, nesmí sesednout.
---
http://www.inventurakrajiny.cz/sipka/
Aquadelic GT, Mafia II, simulátory
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Augi



Založen: 28. 07. 2007
Příspěvky: 782
Bydliště: Čerčany

PříspěvekZaslal: 31. říjen 2008, 15:13:42    Předmět: Odpovědět s citátem

Já doporučuju singletony nepoužívat a všechno předávat přes parametry konstruktorů/metod.
Ta úprava, o které psal semo, je sice pracná, ale rozhodně bych to nenazýval prasečinou a prostě objekt bude mít přístup jen k tomu, co potřebuje. Spíš to svědčí o podcenění analýzy Wink
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 31. říjen 2008, 17:20:20    Předmět: Odpovědět s citátem

...Nevím na jakou stranu barikády se mám přidat... Shocked

No ještě se zeptám jinak...existuje ještě nějaký způsob, jak zamezit tomu aby programátor vytvořil další instance třídy jako je třeba texturemanager?

Teď mě napadá...texturových manažerů může bejt kopa, ale místo, kam se budou ukládat záznamy, že ta či ona textura byla už načtená, může bejt jen jeden...takže teoreticky by to šlo udělat tak, že si vytvořím třídu uložiště textur a odkaz na její instanci bych pak předával v každé nové instanci texturemanageru...no jo, ale co když to nechci dělat ručně...
Co když chci pouze vytvořit texturemanager...tzn. zavolá se konstruktor texturemanageru a v něm se od někud (zatím ještě nevím odkud) veme ten pointer na uložiště....jak to řešit? Mělo by texturové uložiště být singleton? Nebo klasicky přes globální proměnnou?...Ještě mě napadá, že by třída Core byla singleton, vytvořila si jedno uložiště textur, to si pamatovala a při vytvoření nového texturemanageru by se akorát zavolalo Core::getinstance.getstorage no a bylo by to vlastně řešené podobně jak říkal Augi, jen s tím rozdílem, že bych odkaz na uložiště textur nepředával přes parametr konstruktoru/metody ale přes singleton Core...uff...
Možná na to koukám špatně...je to jen nápad a je se to snažím navrhnout tak abych se v tom za půl roku vyznal a hlavně aby se v tom vyznal někdo jiný, protože to budu odevzdávat jako maturitní práci...

Já nevím...jak jsem říkal, do nedávna jsem vše dělal přes globální proměnné...jen se mi to přestalo líbit a začal jsem hledat nějakou alternativu...vzdušnější...
Sám nevím kam jsem se dostal...jestli jsem pokročil nebo vrátil zpátky, ale rozhodně bych tohle rád vyřešil, pro můj dobrý pocit...abych si mohl říct..tak jak jsem to takhle navrhl, tak to bezvadně funguje a bezvadně se v tom vyznám...

Rozhodně toto fórum je tady od toho aby se nad tím diskutovalo a já se rád dozvím věci, které ještě nevím...a myslím, že vy jste mnohem zkušenější než já a tudíž by jste mohli něco předat ostatním, nejen mě...
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Quiark



Založen: 29. 07. 2007
Příspěvky: 816
Bydliště: Chlívek 401

PříspěvekZaslal: 31. říjen 2008, 18:22:22    Předmět: Odpovědět s citátem

To s tím texturovým úložištěm je jen odsunutí problému někam jinam, v podstatě budeš ve stejné situaci.

Třída, která jde vytvořit jen jednou se dá udělat v C++ s pomocí privátního konstruktoru:

kód:

class A {
private:
  A() {};
 
  static bool exists = false;
public:
 static A* CreateInstance() {
   if (A::exists) return NULL;
   
  A::exists = true;
  return new A(); 
  }


Podle mě se v tvé situaci singleton pro TextureManager hodí. Myslím, že nečekáš, že bys někdy potřeboval více instancí. Ono to záleží i na očekávané životnosti projektu, to si musíš objektivně zhodnotit a třeba dojdeš k tomu, že to stejně po dokončení maturitního projektu přepíšeš znova.

A pokud ti jde o jednoduchost, což je docela důležitá věc, tak singleton je lepší volba.
_________________
Mám strach
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> C / C++ Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2, 3, 4  Další
Strana 1 z 4

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna