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ň
|
Zaslal: 30. říjen 2008, 20:09:00 Předmět: Singleton::jak to s ním vlastně je? |
|
|
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... )
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...
Díky za odpovědi... _________________ Opravdovost se pojí s trýzní... |
|
Návrat nahoru |
|
 |
Quiark

Založen: 29. 07. 2007 Příspěvky: 816 Bydliště: Chlívek 401
|
Zaslal: 30. říjen 2008, 20:23:09 Předmět: |
|
|
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 .
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 |
|
 |
Augi

Založen: 28. 07. 2007 Příspěvky: 782 Bydliště: Čerčany
|
Zaslal: 30. říjen 2008, 20:37:04 Předmět: |
|
|
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 |
|
 |
MD

Založen: 29. 07. 2007 Příspěvky: 437 Bydliště: Praha
|
Zaslal: 30. říjen 2008, 21:43:45 Předmět: |
|
|
A uz je to tu zas! : )
No ja si vyzkousel to meneni na 1000 mistech, takze vim, jak to da zabrat
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  _________________ - play with objects - www.krkal.org - |
|
Návrat nahoru |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 30. říjen 2008, 22:05:20 Předmět: |
|
|
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 |
|
 |
OndraSej

Založen: 28. 07. 2007 Příspěvky: 767 Bydliště: Brandýs nad Labem
|
Zaslal: 30. říjen 2008, 22:07:25 Předmět: |
|
|
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 |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 31. říjen 2008, 03:31:19 Předmět: |
|
|
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 |
|
 |
]semo[

Založen: 29. 07. 2007 Příspěvky: 1526 Bydliště: Telč
|
Zaslal: 31. říjen 2008, 10:46:14 Předmět: |
|
|
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 |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 31. říjen 2008, 12:33:12 Předmět: |
|
|
]semo[ napsal: |
eosie: nechápu, proč podruhé? |
Když chceš mít více instancí enginu pro experimentální účely třeba. 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 |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 31. říjen 2008, 12:55:09 Předmět: |
|
|
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 |
|
 |
rezna
Založen: 27. 07. 2007 Příspěvky: 2156
|
Zaslal: 31. říjen 2008, 13:18:48 Předmět: |
|
|
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 |
|
 |
]semo[

Založen: 29. 07. 2007 Příspěvky: 1526 Bydliště: Telč
|
Zaslal: 31. říjen 2008, 13:19:55 Předmět: |
|
|
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 |
|
 |
Augi

Založen: 28. 07. 2007 Příspěvky: 782 Bydliště: Čerčany
|
Zaslal: 31. říjen 2008, 15:13:42 Předmět: |
|
|
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  |
|
Návrat nahoru |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 31. říjen 2008, 17:20:20 Předmět: |
|
|
...Nevím na jakou stranu barikády se mám přidat...
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 |
|
 |
Quiark

Založen: 29. 07. 2007 Příspěvky: 816 Bydliště: Chlívek 401
|
Zaslal: 31. říjen 2008, 18:22:22 Předmět: |
|
|
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 |
|
 |
|