Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
KralLam
Založen: 22. 09. 2007 Příspěvky: 8
|
Zaslal: 7. duben 2008, 12:54:20 Předmět: clenske promenne tridy |
|
|
Ahoj, chtel bych si napsat tridu pro zakladni grafiku a spravu okna. Tuhle tridu bych chtel postavit nad SDL.
//trida.h
class trida {
int sirka,vyska;
...
NastavOkno();
PutPixel();
....
};
Problem je, ze nevim kam mam strcit spravovana data sdl, kam mam ulozit SDL_Surface *obrazovka atd. Do hlavickoveho souboru se mi to prilis davat nechce...to bych tam musel davat includy a uz by to neslo predelat pro jinou knihovnu....vytvorit je nekde ve zdrojaku trida.cpp jako staticke bez prime vazby na tridu se mi taky moc nezda. Jak se to da nejak pekne resit? Dekuji. |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 7. duben 2008, 13:48:46 Předmět: |
|
|
tady se pomerne hodi 'zapouzdrujici' trida (myslim facade, ale z hlavy nevim jmeno toho navrhovyho vzoru), vypada to takto:
hlavicka:
kód: |
class SDL_interface
{
public:
SDL_interface();
~SDL_interface();
void kresli(); .......
private:
struct SDL_interface_implementation * impl;
}
|
.cpp:
kód: |
#includy
struct SDL_interface_implementation
{
// promenne, metody, ...
}
SDL_interface::SDL_interface() { impl = new SDL_interface_implementation(); }
SDL_interface::~SDL_interface() { delete impl; }
void SDL_interface::kresli() { impl->kresli(); }
|
|
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 7. duben 2008, 20:40:20 Předmět: |
|
|
Facade (fasáda) pattern je spíš udělání nějakého pomocného interfacu, aby se s větší množinou netriviálních objektů pracovalo jednodušeji a abys nemusel o těch objektech vědět to, co vědět nepotřebuješ. Př.: WinAPI je fasáda nad jádrem a službami systému.
To, co asi KralLam chce a co měl Yoyo zřejmě na mysli, je Bridge pattern. Zbývá akorát poznamenat, že by se mělo jednat o abstraktní třídy. Viz wikipedie, tam je to krásně popsané: http://en.wikipedia.org/wiki/Bridge_pattern _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Pavel
Založen: 29. 07. 2007 Příspěvky: 54 Bydliště: Litovel
|
Zaslal: 7. duben 2008, 20:46:42 Předmět: |
|
|
Jj, to bude bridge. |
|
Návrat nahoru |
|
 |
Al
Založen: 23. 10. 2007 Příspěvky: 196
|
Zaslal: 7. duben 2008, 23:53:52 Předmět: |
|
|
Podle mě nemáte pravdu.
Tato konkrétní věc se dělá obvykle tak, že mám třídu A, ve které je implementace a třídu B, která je jejím předkem a je vidět v hlavičkovém souboru. Jinými slovy v hlavičkovém souboru mám jen rozhraní, které v jazyce C++ děláme ve formě bázové třídy pro jinou třídu, která ve skutečnosti vše implementuje.
Tento způsob vyžaduje factory (továrnu na objekty), což doufám pro vás není problém (už proto, že to přináší řadu dalších jasných výhod, třeba při používání DLL), ale zas na rozdíl od bridge nemáte v hlavičkovém souboru ani vidět nějaký odkaz na ten implementující objekt.
Poznámka: Když píšu "obvykle se dělá tak...", čerpám čistě z vlastní zkušenosti (ze vzpomínek). Prostě takhle jsem to vždycky viděl dělané v různých knihovnách v C++. |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 8. duben 2008, 00:02:32 Předmět: |
|
|
Al> Tu poznámku o abstraktních třídách už jsem psal výše. Pokud trváš na tom, aby nebyl vidět odkaz na implementující objekt, tak ho prostě skryješ. Třeba takto: http://www.ceske-hry.cz/forum/viewtopic.php?p=8431#8431 _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Al
Založen: 23. 10. 2007 Příspěvky: 196
|
Zaslal: 8. duben 2008, 00:07:39 Předmět: |
|
|
Eosie: Jde mi o to, že tam máte ten pointer - proměnnou jménem "private". To je ten bridge. Když se to udělá jako interface, žádná taková proměnná tam není. Jako mně je to jedno, jak si to kdo udělá, takové to bude mít, jenom prostě ten bridge bych tady já rozhodně nepoužil.
Jo a ten bridge bude blbnout, když někam budu potřebovat předat sebe jako odkaz (this), protože tím předám odkaz na ten vnitřní objekt. Při zdědění pomocí this předám odkaz na celý objekt. |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 8. duben 2008, 00:49:02 Předmět: |
|
|
jo, bridge sem mel na mysli, ty odborne pojmy se mi motaji, diky za upresneni
jinak interface si myslim ze slouzi ke kapanek jinemu ucelu, a zrovna ke skryti implementace bych jej nepouzil - teda ne ze by to neslo, nebo bylo spatne, ale proste se mi to nezda  |
|
Návrat nahoru |
|
 |
Augi

Založen: 28. 07. 2007 Příspěvky: 782 Bydliště: Čerčany
|
Zaslal: 8. duben 2008, 08:24:05 Předmět: |
|
|
Yossarian napsal: |
jinak interface si myslim ze slouzi ke kapanek jinemu ucelu, a zrovna ke skryti implementace bych jej nepouzil - teda ne ze by to neslo, nebo bylo spatne, ale proste se mi to nezda  |
No mně se to právě docela zdá Když to uděláš tak, jak píše Al, tak budeš v aplikaci používat jen interface úplně nezávisle na nějaký implementaci. Jedinej bod "nějakým" způsobem specifikující konkrétní používaný objekt bude volání nějaké metody factory (což je součást knihovny).
Typickým příkladem použití je třeba práce s databází v .NET. Můžeš sice pracovat přímo s konkrétní třeba MySQLConnection, MySQLCommand, MySQLParameter atd., ale imho je lepší všude pracovat s implementačně nezávislými ISQLConnection, ISQLCommand, ISQLParameter atd. Jediným bodem, kde pak specifikuješ používanou databázi, je nějaká factory, která si může nastavení o používané databázi tahat třeba z prd...konfuguračního souboru Nebo řekneš té factory, jakou databázi má používat, jen jednou na začátku programu. A podle toho nastavení Ti ta factory bude sypat konkrétní implementace jednotlivých rozhraní, takže pokud nebudeš dělat nějaký DB kejkle, tak tím získáš aplikaci nezávislou na používané DB...
S tímhle použitím v Microsoftu imho docela počítali, takže v praxi Ti pak stačí, aby ta factory uměla vytvořit myslím jen ISQLConnection (+ možná ještě jednu třídu, už nevim) a to rozhraní už pak obsahuje metody CreateCommand, které obsahuje CreateParameter atd. - takže udělat DB nezávislou aplikaci v .NET je pak fakt brnkačka  |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 8. duben 2008, 20:59:13 Předmět: |
|
|
no jasny, ale pak musis navrhnout rozhrani opravdu nezavisle na implementaci.
je zbytecne toto pouzivat v pripade, ze mas ciste specializovanou tridu, a jenom nechces aby byly videt soukrome vlastnosti (to se tu ted nedavno resilo, ne? aby programator prasacky nehrabal na private), at uz z duvodu 'zabezpeceni', nebo proto ze je zbytecne na ne videt.
kdyz mas tridu SDL_Bitmap { };, a pocitas s nejakymi specifickymi vlastnostmi pro SDL, tak asi tezko udelas interface IBitmap a v zachvatu multiknihovnality na to naroubujes allegro (k cemuz rozhrani svadi) |
|
Návrat nahoru |
|
 |
Al
Založen: 23. 10. 2007 Příspěvky: 196
|
Zaslal: 9. duben 2008, 14:42:24 Předmět: |
|
|
Předchozí příspěvek (Yossarian) mě děsí!!!
1. Rozhraní "musím" navrhnout nezávisle? Myslím, že přesný opak je pravdou. Rozhraní můžu navrhnout jakkoliv, třeba i závisle, ale právě já ho přece chci mít úplně nezávislé na implementaci. V tomto případě ale implementující třída bude přímo dědit třídu veřejnou (class Impl : public Interf), takže není důvod, aby "class Impl" měla nějaké jiné veřejné metody než přesně tytéž, co má "class Interf". Ty dvě třídy tedy budou mít stejné veřejné metody, a stejně to rozhraní bude nezávislé na implementaci.
2. Ať už ty proměnné "schováme" jakkoliv, tak porát platí, že viditelnost proměnných není vůbec nástrojem bezpečnosti, takže diskutovat o "zabezpečení" v této souvislosti je z principu nesmyslné.
3. Rozhraní implementované dědičností v C++ tam nedáváme proto, abychom pak implementovali něco s nějakými jinými knihovnami, ale skutečně proto, abychom oddělili rozhraní = vnější komunikaci od implementace = vnitřní struktury. |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 9. duben 2008, 20:40:32 Předmět: |
|
|
Myslím, že rozhraní by se mělo dělat tam, kde se implementace může měnit. Pokud jsem si jistý, že v budoucnu nikdy nebudu potřebovat více různých implementací jednoho objektu, tak interface nedělám. Pokud bych to potřeboval, transformovat nějaký obyčejný objekt na interface a z něj ten objekt podědit už je celkem hračka (pokud jsou objekty dostatečně jednoduché a starají se jenom o to svoje). Stejně napoprvé ta rozhraní většinou nenavrhneš dobře, tak proč to hrotit hned na začátku. Dělat zvlášť rozhraní úplně ke každé třídě jen proto, že si to Al myslí, mi přijde kontraproduktivní.
No a taky jde samozřejmě o to, že ne-virtuální metody jdou snadno inlinovat (a když nejsou v headeru, tak je umí inlinovat linker (ve VC++)). _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Al
Založen: 23. 10. 2007 Příspěvky: 196
|
Zaslal: 9. duben 2008, 20:51:46 Předmět: |
|
|
Mimochodem, bavíme se pořád ještě o té původní otázce KralLam? Já když čtu ty vaše zamyšlení nad tím, jak je problém navrhnout rozhraní, aby bla bla bla, tak mám dojem, že ne. To rozhraní přece bude úplně stejné jako public metody v té třídě, ke které to rozhraní píšu. Fascinuje mě, jak tady už dva uživatelé nazávisle na sobě (teda pokud to nejsou nějací spolužáci či čtenáři stejných knih) prezentují pojem rozhraní jako nějakou mýtickou entitu zahalenou tajemstvími a nadpřirozenými vlastnostmi. Rozhraní je ale úplně obyčejná věc (chtělo by se říct "z masa a kostí..." ).
K věci: Problémy, které jsem uvedl na konci příspěvku 8.duben 2008, 01:07:39, mi přijdou jako dost důležitý argument pro použití rozhraní v dané situaci.
A když už je řeč o tom, co na co není, jak psal Eosie, tak bridge určitě není primárně na to, když teprve dělám novou třídu a chci schovávat proměnné někam jinam, ale na to, když už nějakou třídu mám a jeji rozhraní nemůžu měnit. Naopak pojem "rozhraní" se běžně používá v mluvě - vše, co je v hlavičkovém souboru, je přece automaticky rozhraní. Hlavičkový soubor přece nejčastěji obsahuje prototypy a dávám tím uživateli informaci, jaké komunikační rozhraní mu nabízím. Rozhraní coby programátorský nástroj je pak implementací té myšlenky. Každá třída ale má nějaké rozhraní, je to "vše public", co v té třídě je. Kdo v rozhraní vidí nějaké nadpřirozené bytosti, tak dost přehání. |
|
Návrat nahoru |
|
 |
Marek

Založen: 28. 07. 2007 Příspěvky: 1782 Bydliště: Velká Morava
|
Zaslal: 9. duben 2008, 20:59:17 Předmět: |
|
|
1) rozhraním v mém příspěvku (a ve všech jiných příspěvcích) myslím abstraktní třídu (pro c++)
2) bridge už bych neřešil, to jsem možná přestřelil nepochopením zadání _________________ AMD Open Source Graphics Driver Developer |
|
Návrat nahoru |
|
 |
Yossarian

Založen: 28. 07. 2007 Příspěvky: 274 Bydliště: Šalingrad
|
Zaslal: 9. duben 2008, 21:10:31 Předmět: |
|
|
Al neumi cist. Reagoval sem na Augiho myslenku o vymene DB stroje na pozadi - musi byt dobre navrzene rozhrani. Jinak taky pouzivam rozhrani, bridge jen minimalne, ale stejne si myslim ze oba pristupy k reseni jednoho maji 'z kontextu' byt pouzity jinak. |
|
Návrat nahoru |
|
 |
|