dev.gamez.lv Forum Index dev.gamez.lv
Latvian Game Developers Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups 

Koda organizeeshana

 
dev.gamez.lv Forum Index -> Programmēšana
View previous topic :: View next topic  
Author Message
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Mon Apr 30, 2007 6:27 pm    Post subject: Koda organizeeshana

Te es uzsaakshu jaunu threadu ar jautaajumu seriju par koda organizeeshanu. Ceru, ka veel kaadam (ne tikai man) shis threads noderees.
Pirmais jautaajums - viena objekta izmantoshana gan maates (parent), gan beerna (child) klasee.
Piemeers:
Ir klase CApplication, kura izmanto CLogger klasi (lai ielogotu visas programmas darbiibas).Tai ir apakshklase state - MainMenu.
Sheema izskataas shaadi:
CApplication
|
|__>CLogger
|
|__>CMainMenu

Tachu pie CLogger klaat grib tikt arii CMainMenu. Kaa tagad organizeet kodu?
Ir 4 varianti:
1) Uztaisiit CApplication kaa singletonu un ljaut piekljuut jebkuram pie CLogger. Tachu parasti shaadi objekti ir private vai protected, taadeelj naaksies veidot funkciju GetLogger();
2) Uztaisiit CLogger kaa singletonu. Tachu ko dariit, ja mees pie CLogger klases klaat netiekam (piemeeram, mees izmantojam kaadu engine ar iebuuveetu Logger, kuru nevaram mainiit)?
3) Padot pointeri uz CLogger CMainMenu konstruktoraa un peec tam saglabaajam sho pointeri ieksh CMainMenu.
4) Visaas funkcijaas, kur CMainMenu izmanto sho CLogger, padodam to kaa parametru. Piemeeram, LoadMainMenu(CLogger* pLogger).

Varbuut ir veel kaadi varianti?
Galvenais jautaajums ir: kaa Juus organizeetu shaadu kodu?

Personiigi manaa kodaa CLogger klasi nav iespeejams mainiit, jo taa ir kaada engine klase.

P.S. Peec atbildeem sekos naakoshais jautaajums par koda organizeeshanu.
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon Apr 30, 2007 6:58 pm    Post subject:

CMainMenu ir CApplication apakšklase? Tad vajag uztaisīt CLogger kā CApplication protected memberu.

elvman wrote:
Tachu ko dariit, ja mees pie CLogger klases klaat netiekam (piemeeram, mees izmantojam kaadu engine ar iebuuveetu Logger, kuru nevaram mainiit)?

Nowrapot CLogger ar Singletona templeitu, kuram ir pārlādēts -> operators.

Quote:
4) Visaas funkcijaas, kur CMainMenu izmanto sho CLogger, padodam to kaa parametru. Piemeeram, LoadMainMenu(CLogger* pLogger).

Noteikti nē.
Back to top
View user's profile Send e-mail
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Mon Apr 30, 2007 7:02 pm    Post subject:

CMainMenu ir CApplication apakshklase. Un ko taalaak? Es pie shii membera tik un taa netieku.
Code:
error C2248: 'CApplication::m_pLogger' : cannot access protected member declared in class 'CApplication'

_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon Apr 30, 2007 7:04 pm    Post subject:

Em.. tu protected memberu atšķirību no private/public zini? Man škiet, ka tu nemanto klasi publiski.
class CMainMenu : public CApplication { ...

Jā un vēl viens variants: vajag neizlikties, ka CLogger klases instance nav globāls mainīgais un nodeklarēt to globālu un lietot laimīgi no visurienes. Imho vislabākais variants. Tā vismaz mēs skvēros daram, kad lietojam logošanu uz std::clog.
Back to top
View user's profile Send e-mail
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Mon Apr 30, 2007 7:09 pm    Post subject:

Nee, tu nesaprati. Ar apakshklasi esdomaaju dependency:

class CMainMenu
{
protected:
CLogger* m_pLogger;
CMainMenu* m_pMainMenu;
}

Starp citu aizmirsu veel vienu variantu - defineet friend klasi. Tad CGame vareetu tikt klaat arii pie CApplication protected memberiem. Tagad tieshaam saaku apsveert ideju izmantot globaalus mainiigos, bet nesen lasiju rakstu, ka ar Singletoniem un globalajiem mainiigiem PILNIIBAA zuud OO jeega. Paradoksaali, bet alternatiivs piemeers, kaa sho visu panaakt savaadaak netika dots.
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Mon Apr 30, 2007 10:00 pm    Post subject:

elvman wrote:
Nee, tu nesaprati. Ar apakshklasi esdomaaju dependency

Apkašklase jau nozīmē mantota klase :) Tas ko tu rādi ir parasts klases memberis.

Quote:
Starp citu aizmirsu veel vienu variantu - defineet friend klasi.

friendi manā uztverē nav labi, tie jauc enkapsulāciju - cita klase var vandīties pa citas klases memberiem bez nekādas kontroles.

Silti iesaku tev ņemt globālā mainīgā variantu. Nevajag manīt sevi (un citus, kuriem dosi/rādīsi savu kodu).

Quote:
Paradoksaali, bet alternatiivs piemeers, kaa sho visu panaakt savaadaak netika dots.

Tā jau tajā programmēšanā ir - nav viena "vispareizākā" ceļa. Ir varianti un daudz varianti. Vajag apsvērt variantus un izvēlēties mazāk kaitīgo.
Un lasīt var daudz un dikti. Lasīt var arī, ka OOP ir slikts un C rullē. Vajag saprast, kas ir globāls un kas nav. Logeris tev ir globāls, un tas vai tu to noslēpsi singletonā, vai arī globālā mainīgajā vai globālajā funkcijā, kura atgriezī no kautkurienes izraktu objektu, nemainīs lietas būtību - logeris ir un paliks globāls (pēc būtības, nevis C++ sintakses). Atšķirsies tikai sintakse kā tu pie tā piekļūsi.
Back to top
View user's profile Send e-mail
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Mon Apr 30, 2007 11:31 pm    Post subject:

Palasiju arii aarzemju forumus un tur tika teikts, ka tas nav slikti izmantot globaalos mainiigos.Taa laikam arii uus jaadara.

Bet tagad veel viens jautaajums. Atceros, ka tu bubu man stastiji, ka juus censhaties savaa kodaa, katraa funkcijaa return izmantot tikai vienu reizi. Doshu piemeeru:
Man ir klase, kurai ir funkcija bool Setup(); Taa atgriezh true, ja viss notika kaa naakas, bet false, ja notika kljuuda.Parasti, shaadaa situaacija kods tiktu organizeets shaadi:
Code:
bool Setup()
{
  if (!SetupVideo())
     return false;
  if (!SetupAudio())
     return false;
  if (!SetupBla())
     return false
  if (!SetupBlaBla())
     return false;

  return true;
}

Ko dariit shaadaa situaacijaa? Manupaat, efektiivaak, kaa es to izdariju, nav iespeejams. Paareejie varianti sanaaks ljoti gari, vai arii ar goto un subiem.
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
SkyD



Joined: 04 Oct 2006
Posts: 67

PostPosted: Mon Apr 30, 2007 11:42 pm    Post subject:

Code:
bool Setup() {
  if (!SetupVideo() or !SetupAudio() or !SetupBla() or !SetupBlaBla()) {
     return false;
  } else {
    return true;
  }
}
Back to top
View user's profile
elvman
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 09 Apr 2003
Posts: 1278
Location: Kuldiga

PostPosted: Mon Apr 30, 2007 11:53 pm    Post subject:

Ok, mans piemeers bija paaraak vienkaarshs. Parasti starp setupiem ir jaasagatavo kautkaadi dati (piemeeram pirms kaada setupa rezervee atminju buferim vai ko tamliidziigu). Taadaa gadiijumaa tas nestraadaas.
Un ko dariit, ja katram erroram ir jaatgriezh savs specifisks error kods? Protams var deklareet vienu mainiigo, kas saturees sho error kodu un tas tiks atgriezts tikai funkcijas beigaas, bet manpupraat, tas ir bezjeedziigi. Pie tam, tu bubu esi vieniigais, no kaa es ko taadu biju dzirdeejis. Tas gan ir interesants piegaajiens, bet nekad neesmu redzeejis tadu kodu (gan MicroSoft savos SDK, gan lielaakaa dalja tutorialu parasti returno pie katra errora).
_________________
long time; /* know C */
Back to top
View user's profile Visit poster's website
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Tue May 01, 2007 12:12 am    Post subject:

-- slikts posts --

Last edited by bubu on Tue May 01, 2007 12:20 am; edited 1 time in total
Back to top
View user's profile Send e-mail
bubu
Indago Uzvarētājs
Indago Uzvarētājs


Joined: 23 Mar 2004
Posts: 3223
Location: Riga

PostPosted: Tue May 01, 2007 12:19 am    Post subject:

SkyD wrote:
Code:
bool Setup() {
  if (!SetupVideo() or !SetupAudio() or !SetupBla() or !SetupBlaBla()) {
     return false;
  } else {
    return true;
  }
}

Šāda koda vietā daudz labāk būtu rakstīt:
Code:
bool Setup()
{
  return !SetupVideo() || !SetupAudio() || !SetupBla() || !SetupBlaBla();
}

Taču tas ir grūti lasāms un papildināms.

Tas ko vajag darīt šādā kodā - ir lietot exceptionus: throw FatalError(INVALID_FILE), throw FatalError(NO_MORE_MEMORY) un tml. Un throw'ot vajag nevis no lielās Setup funkcijas, bet no apakšējo SetupX() funkcijām.
Setup'u tu taču dari tik vienreiz (vai dažreiz) un nevis bieži. Tāpēc exceptioniem te ir īstā vieta - nebūs nekādi lielie performance penalty, kuri būtu, ja tu sāktu throw'ot no render funkcijas iekšējā loopa kautkur.

Quote:
Pie tam, tu bubu esi vieniigais, no kaa es ko taadu biju dzirdeejis. Tas gan ir interesants piegaajiens, bet nekad neesmu redzeejis tadu kodu (gan MicroSoft savos SDK, gan lielaakaa dalja tutorialu parasti returno pie katra errora).

Smieklīgi, bet mums darbā šādu nosacījumu uzspieda pats Microsofts ;)
Un tutoriāļi ir tutoriāļi, tie koncentrējas uz vajadzīgo tēmu par ko tie ir, un nevis uz labu un "skaistu" kodu.

Quote:
Atceros, ka tu bubu man stastiji, ka juus censhaties savaa kodaa, katraa funkcijaa return izmantot tikai vienu reizi
.
Es jau nesaku, ka vajag tikai tā un vienīgi tā darīt. Mēs jau cenšamies tikai tāpēc, ka programmatūras koda guideline tā pieprasa. Man pašam tas ne īsti pie sirds iet. Jo kā nekā C++'ā ir īpaši labi pielietojama RAII idioma, kad klase savā konstruktorā izdala atmiņu/atver failu/sagrābj resursu un savā destruktorā atbrīvo atmiņu/aizver failu/atbrīvo resursu tādējādi early-returns nav nemaz tik slikts kā C valodā, kurā tas var daudz slikta darīt. Tas viens returns tika prasīts tāpēc, ka C valodā, piemēram, ja tu izdali atmiņu ar malloc/atver failu ar fopen/... tad tev obligāti PAŠAM jāatcerās atbrīvot/aizvērt to visu, kad ar return atgriezies kautkur atpakaļ. Un ja tev ir 10 return'i, tas viss jādara 10 vietās. Un kas būs, kad kāds cits tavā kodā pieliks vienu jaunu return'u? Tad viņam arī jāatcerās, kas un kā ir jāatbrīvo/jāaizver. C++'ā šāda problēma ir mazāka, jo te nāk RAII - automātiski konstruktri/destruktori stekā izdalītajiem objektiem (std::vector, std::fstream, utt). Vajag mazāk lietas atcerēties, jo vairāk lietas notiek automātiski.

Early returns ir labs, ja vien tu to dari pašā funkcijas sākumā kā pārbaudi uz argumentiem/ieejas parametriem. Tipa pārbaudi ir A labs, jā/nē? ja nav tad iziet no fjas, ja ir tad turpināt. Vai arī šos early returns lietot kautkādos dziļi ieliktos ciklos, kad pie atrasta elementa, vajag iziet ārā no fjas.
Back to top
View user's profile Send e-mail
Display posts from previous:   
dev.gamez.lv Forum Index -> Programmēšana All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group