» »

Coding Style

Coding Style

hatch ::

Okej.. na forumu sem opazil nesteto folka, ki ne znajo pisat komentarjev, izbirat imen funkcij in spremenljivk... zato pisem ena osnovna pravila kodiranja.
Jaz vedno uporabljam anglesko imenovanje funkcij in spremenljivk.. izkljucno zato, ker so vse built-in zadeve ze v anglescini.. in mesanje angleskega in slovenskega jezika je slabo. Ce so ze vse built-in funkcije v anglescini (open, close, exit..), naj bojo se nase.

1. Enoten stil kodiranja cez cel projekt

- Enotna velikost in stil (insert tabs||spaces) tabulatorjev
- Enoten stil function headerjev
- Maximalna sirina (ponavadi je to 80 ali 100 znakov.. torej razdelite dolge vrstice v vec vrstic, ce prekoracite to mejo)

Torej vsi udelezenci projekta morajo imeti enake nastavitve svojih editorjev, da vse zgleda enako za vse. Vecino editorjev se da nastavit tako da tabulatorji delajo kot so zastavljeni. (osebno uporabljam Visual Studio na windowsih in FTE editor na linuxu.. pri obeh se da nastavit tabulatorje) pri VS.NET -> Tools->Options...->Text Editor->All Languages->tabs

2. Smiselno imenovanje spremenljivk in uporaba madzarske notacije


Madzarska notacija (aka Hungarian Notation) je stil poimenovanja spremenljivk. Pred vsako integer spremenljivko damo naprimer crko 'i'.. naprimer:
int iSelectionCount;

Hungarian Notation... nekaj jih se manjka..
'ul' - unsigned long (UINT32)
'll' - long long (INT64)
'ull' - unsigned long long (UINT64)
'e' - enumeracija
itd...

Spremenljivke pa naj bodo imenovane glede na to cemur so namenjene. Naprimer omenjena spremenljivka 'iSelectionCount' je namenjena hranjenju stevila oznacenih elementov. Uporaba velikih in malih crk je tudi pomembna za razlocevanje med imenom spremenljivke in prefixom madzarske notacije.
Informacije o spremenljiki naj bodo sortirane po pomembnosti od leve proti desne, razlocene z velikimi/malimi crkami... naprimer:
iSelectionCountMin
iSelectionCountMax
szSelectionName

Nekako tako kot ce bi delali s structi..
pSelection->count.iMin
pSelection->count.iMax
pSelection->szName

3. Imenovanje funkcij
Podobno kot spremenljivke, naj bodo jasno poimenovane, da tocno vemo za kaj se gre.

int preveri(char *ime); - To je slabo!

int CheckFileIntegrity(char *szFileName); - to je veliko bolj jasno, in tocno vemo za kaj se gre

se bolje:
int File_CheckIntegrity(char *szFileName); - tako naredimo, ce imamo veliko funkcij za manipulacijo filov..

4. Error Handling
Ok.. veliko vas pise funkcije kar brez returnov ali pa z bool returni, kar je zelo slabo iz stalisca error handlinga.
Ce funkcija ni casovno-kriticna (torej da sam klic funkcije casovno zanemarljiv glede na cas izvedbe) naredite error-handling kot se spodobi.

Naprimer takole:
int CheckFileIntegrity(char *szFilename)
{
    int     iRet = 0;
    FILE   *fdFile;

    fdFile =  open(szFileName, "r");
    if (fdFile == NULL)
    {
        iRet = GetLastError();
        return iRet;
    }    

...

    return iRet;
}

Ce pa je funkcija casovno kriticna.. naprimer izracunavanje normal v kaki 3D aplikaciji, se error-handlinga ne dela.. ampak se zagotovi da je input parameter pravilen.

Torej.. vedno uporabljajte return variable za error-handling, ce je le mogoce.. za output spremenljivke pa uporabljajte 'parameter as output variable' To se pa naredi tako:
int GetStringSize(char *szInput, int *piSize)
{
    if (szInput == NULL) return ERROR_EMPTYSTRING;
    
    *piSize = (int)strlen(szInput);
    
    return NO_ERROR;
}

In potem klicemo funkcijo z:
iRet = GetStringSize(szName, &iSize);
in se nam velikost zapise v iSize.

5. Komentarji
Komentarji so zelo pomembna zadeva pri kakrsnemkoli programiranju. Ce upostevate prejsnja navodila za imenovanje spremenljivk in funkcij, so komentarji znotraj kode potrebni samo redkokdaj. Ponavadi samo ce pride do veliko branchinga, ali pa ce uporabimo kak poseben trik, ki ni viden na prvi pogled.

Zelo pomembni so pa tako imenovani function headerji. Gre za blok komentarja, ki opise kako funkcija deluje. Vsebovati mora:
- Ime funkcije
- naslov funkcije
- Return spremenljivka (kaj vraca in kdaj!)
- INPUT in OUTPUT parametri
- Kratek opis funkcije (kdaj se kaj zapise v OUTPUT)
- Special case scenario (ce je kaka zadeva zaradi cesar funkcija ponavadi faila.. ali kaj podobnega)
- Mozni flagi! (ce imamo kak flag parameter, napisite se vse mozne flage in kaj naredijo)

Recimo function header za prejsnjo funkcijo GetStringSize:
/*******************************
* GetStringSize
*
* Gets size of specified string
*
* /INPUT/ char *szInput    Input string
* /OUTPUT/ int *piSize     Output string length
*
* return:
* On success returns NO_ERROR
*
* description:
* Gets size of string szInput and puts it's size into piSize.
*
* If szInput is NULL, function fails and returns ERROR_EMPTYSTRING
*
 *******************************/


Bom verjetno se kej napisal.. sam tolk za zdele.
  • spremenil: Vesoljc ()

hatch ::

Mal problemov z odmiki.. upam da se znajdete. Bom jutri postal se o uporabi #define-ov in macrojev.

Trubadur ::

Naj da moderator to za sticky
Berite Thomasa!

Sergio ::

Pod hatchev post se lahko le podpišem.

Edinole nekaj: jaz programiram tako, da so zaviti oklepaji v novi vrstici, kar pa notaciji ne ustreza.

public static void main(String[] args)
{
  ...kodakodakoda...
}


Ponavadi programiram tako da je meni logicno, na koncu pa stvar pretvorim z editorjem (Eclipse in VS.Net imata to zelo lepo postimano)
Tako grem jaz, tako gre vsak, kdor čuti cilj v daljavi:
če usoda ustavi mu korak,
on se ji zoperstavi.

Vesoljc ::

jaz programiram tako, da so zaviti oklepaji v novi vrstici, kar pa notaciji ne ustreza.

kriminalc! ;)
Abnormal behavior of abnormal brain makes me normal...

Vesoljc ::

amm, hatch upam, da ne bos jezen 8-)
<b>C++</b> coding style
Abnormal behavior of abnormal brain makes me normal...

trs ::

Samo se nekaj ... gotoji za errorhandling v Cju rulz ;) Marsikdo pravi, naj se gotoji nikoli ne uporabljajo, vendar znajo bit ZELO uporabni.

Sicer pa hungarian notation meni osebno ni vsec. Sploh pa ne za lokalne variable. Ce ne ves kasnega tipa je variabla, pol ne ves niti kaj pocne v tisti kodi ;) (moje osebno mnenje, nekateri ga kar veselo uporabljajo).

Pa za funkcije imam tudi raje old-school imena funkcije file_check_integrity() namesto FileCheckIntegrity().

Sicer pa verjetno je to stvar navade ... tisti ki, pridejo iz Windows okolja imajo najbrz raje xyzCapitalizeFunctionsNames(), Unixasi pa najbrz raje underscored_functions_names()... kdo ve ;)

Aja se nekaj. NIKOLI se v Cju ne uporablja // za komentarje, ceprav jih VC pozre!!

Drugace pa tisti ki delate v Linuxu (oz. s katerimkoli GCC compilerjem), ni slaba praksa ce si vklopite cim vec warningov(-ansi -pedantic -Wall -W -O).

hatch ::

Definitivno so gotoji odlicna zadeva za error handling.. tudi sam jih redno uporablam za ta namen. Primer:

int FileCheckIntegrity(char *szFilename)
{
int iRet;
char *szBuf = NULL;
...
szBuf = (char*)malloc(128);
...
if (FAILED)
{
iRet = ERROR_BLABLA;
goto _EXIT_;
}

_EXIT_:
if (szBuf) free(szBuf);
return iRet;
}

BigWhale ::

Saj tam med

goto _EXIT_
}

in

_EXIT_:

manjkajo se ...

Mar ne? Zakaj bi sicer goto exit? ;)

kopernik ::

>1. Enoten stil kodiranja cez cel projekt

Se popolnoma strinjam.

>2. Smiselno imenovanje spremenljivk

Tudi tukaj.

> in uporaba madzarske notacije

Tukaj pa ne, ker sovražim madžarsko notacijo :-) Ampak dobro, to so osebne preference.

>3. Imenovanje funkcij

Tudi tukaj se strinjam.

>4. Error Handling

V veliko jezikih obstaja mehanizem izjem, ki zagotavlja boljše obravnavanje izjemnih/nepričakovanih situacij. Sicer so tudi returni ok (predvsem pri časovno kritičnih odsekih), če se tak princiop uporablja dosledno.

>5. Komentarji

Se strinjam, da so zelo pomembni. Načeloma naj bi veljalo, da ni potrebno komentirati kako dela koda (programerski vidik), temveč bolj razloge zakaj sem to naredil, kaj je namen določene metode, ipd. Seveda poleg opisov parametrov, možnih izjem, itd. kar je že hatch opisal.

No, ker se je avtor omejeval na C, bom jaz podal še kakšen komentar za Javo:

1. Exceptioni:
V Javi(seveda tudi drugje, npr. C++, Python, Delphi) obstaja poseben mehanizem ravnanja z izjemami, ki je priročen iz več vidikov:
- preglednejša koda
- jasno definirane izjemne situacije
- programer je prisiljen že v compile-time misliti na izjeme in se na njih odzivati
(primer konekcije na bazo: kaj se zgodi, če baza ni dostopna ? se zna program nazaj povezati nanjo, ko je spet dostopna?)
Primer:
String niz = "tole pa ni stevilo";
try  {
    int number = Integer.parseInt(niz);
} catch(NumberFormatException e) {
    System.out.println("Napaka pri konvertiranju stevila:\t" + niz);
}


2. Poimenovanja
Poleg pametnega poimenovanja spremenljivk in metod, je dobro, če so poimenovanja smiselna tudi pri razredih, vmesnikih in paketih.

Razredi in vmesniki:
Nenapisano pravilo pri Javi je, da se razrede poimenuje z načinom TitleCase (velike črke začetkov besed) - primer imena: ServerConnectorFactory.

Paketi:
Spet nenapisano pravilo je, da so vse črke v imenu male črke. Poleg tega pa je dobro, da se v ime paketa vključi tudi ime domene v obratnem vrstnem redu (zatem pa navadno ime projekta, itd). Primer:

net.manfreda.mojprojekt.server.connectors

Ime je sicer lahko poljubno, taka konvencija (pametno je torej imeti unikatna imena paketov -> domene so unikatne) pa obstaja zato, da ne pride do napak pri nalaganju razredov. Primer problematične situacije:
Odločim se za neko poljubno ime paketa (npr. database.data) in v njemu naredim razred z imenom Person. Ker so taka poimenovanja precej splošna, je možno, da bo še nekdo drug nekje ustvaril enak paket z enakim imenom razreda. Če se bo (sicer zelo malo možnosti) kdaj zgodilo, da se bodo vajini razredi nalagali v isti instanci JVM-ja, lahko pride do napake.

2. Komentarji
V Javi obstaja poseben splošno sprejet način formatiranja komentarjev, ki ga je pametno upoštevati. En primer vmesnika (interface) s komentarji, skrajšan :

/**
 * This interface defines standard method to access server facilities. Since clients are not 
 * allowed to directly access resources (such as database), they should use this interface to
 * gather information they need.
 *
 * NOTE: each method can throw ServerConnectorException in order to notify clients of exceptional
 * conditions. 
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: Podjetje</p>
 * <p>Created: 26. 1. 2004</p>
 * @author JanM
 * @version 0.1
 */
public interface IConnector
{
  /**
   * Returns the id of implementing connector.
   *
   * @throws ServerConnectorException in case of general unexpected condition (system errors)
   */
  public String getId() throws ServerConnectorException;
  
  /**
   * Check if specified user has privileges of Home User.
   * <br />
   * @param userSpecificationNumber
   * @return true, if user hase privileges of Home User
   *         false, otherwise
   * @throws ServerConnectorException in following cases:
   * - userSpecificationNumber does not exist
   * - userSpecificationNumber is locked
   * - general unexpected condition occurs (database unavailable, system errors)
   */
  public boolean isHomeUser(String userSpecificationNumber) throws ServerConnectorException;
}


Če se držimo takega formata, lahko celotno dokumentacijo vse kode zgeneriramo s posebnim, Javi priloženim orodjem javadoc. Rezultat je html prezentacija celotne kode (primer uradne dokumentacije J2EE). Ker je rezultat html, lahko vidite v komentarjih tudi html tage ... Javanski komentarji vsebujejo tudi rezervirane besede (npr. @throws), ki javadoc orodju povejo, da je potrebno ta del komentarja posebej obravnavati.

Stil kodiranja
Tukaj bi samo podal code convention, ki ga predlaga SUN. Karkoli že izberete, držite se navodil, ki jih je podal hatch.

Toliko zaenkrat :-)

Zgodovina sprememb…

  • spremenil: kopernik ()

Sergio ::

kopernik:

Pri exception handlingu pojdi še korak dlje in išči več exceptionov na enkrat.

String nizNiSt = "tole pa ni stevilo";
String nizVenArray = "presegli smo okvirje arraya";
try  
{
    int number = Integer.parseInt(niz);
    b = a[number];
} 
catch(Exception e) 
{
    if (e instanceof NumberFormatException)
      System.out.println("Napaka pri konvertiranju stevila:\t" + niz);
    else if (e instanceof ArrayOutOfBoundsException)
      System.out.println("Napaka pri dostopu do arraya:\t" +nizVenArray);
}
Tako grem jaz, tako gre vsak, kdor čuti cilj v daljavi:
če usoda ustavi mu korak,
on se ji zoperstavi.

kopernik ::

Sergio, podal sem najenostavnejši primer. Sicer pa instanceof operator pri exceptionih kao ni zaželjen (zaradi nepreglednosti), temveč naj bi kar nizal catch stvake enega za drugim:

String nizNiSt = "tole pa ni stevilo";
String nizVenArray = "presegli smo okvirje arraya";
int[] a = { 1, 2, 3 };
try  
{
    int number = Integer.parseInt(nizNiSt);
    b = a[number];
} 
catch(NumberFormatException e) 
{
    System.out.println("Napaka pri konvertiranju stevila:\t" + nizNiSt);
}
catch(ArrayIndexOutOfBoundsException e) 
{
    System.out.println("Napaka pri dostopu do arraya:\t" +nizVenArray);
}

Zgodovina sprememb…

  • spremenil: kopernik ()

hatch ::

Da bigwhale:)

Drgac je pa se ena varianta da uporabljas normalne returne, brez goto-jev in s cleanupom.. to s __try in __finally

kopernik ::

Tale tema naj ostane zgolj pri priporočilih glede stila kodiranja. Za vse ostalo naj se ustvari nova tema. Zadnje komentarje sem brisal.

OwcA ::

Madžarska notacija pri programiranju kakšnih čudes z win32 API je skleda polna smeha. ;)

Tudi drugače to ni nujno najboljša pot. Če recimo spremeniš tip globalne spremenljivke takoj nastane packarija, oziroma je kodo kanček težje vzdrževati. Takisto je nesmiselna pri kodiranju v kakšnem skriptnem jeziku, ki nima tako rigidno zastavljenih podatkovnih tipov.
Otroška radovednost - gonilo napredka.

jeti51 ::

Ravno tam je še kako smiselna, IMO. Če ima vsaka spremenljivka točno določen tip, te prevajalnik opozori na kakšne neumnosti (npr. množenje števila in recimo textboxa, čeprav ta je že res huda :)), medtem ko se pri kakšnih skriptnih jezikih napako opazi šele med izvajanjem. Zaradi se mi zdi bolje, da lahko iz imena takoj razbereš tip spremenljivke, da se izogneš takšnim neumnostim.

OwcA ::

To je res, čeprav ne tako drastično, ker kljub vsemu nimaš na voljo polnega obsega operatorjev za poljubni tip. Po drugi strani se pa ponekod ne moreš izogniti skakanju med tipi (recimo kakšne inicializacje z null)
Otroška radovednost - gonilo napredka.

Exilian ::

hmm. a kdo odvas naredi npr. types.h kjer preimenuje nadležno dolga imena standardnih tipov, ker osebno sovražim vsakič tipkat unsigned long; v recimo ulong_t
It's not the opensource i hate.
It's the fanclub I cannot stand.

64202 ::

Saj moras, recimo std::map<std::string, std::string>::const_iterator :|

Mislim, da je ta tema "dokaz", da c/c++ sux. Java kolikor stvari zadane, jih se vec zafrkne (negarantirani finalizerji, zelo svohen sistem tipov, ...). C# 2.0 se nisem prestudiral, ampak dvomim v kak velikanski napredek. Koliko casa bomo se obsojeni na jezike, ki uporabljajo znanje iz 60/70-tih?

Exilian ::

64202: oo dj.. kr glava me začne bolet samo da se spomn na template.....
kar se tiče znanja iz 60tih: sj drugač ne more biti ker se jeziki gradijo na prednikih (asm->pas->c->c++->java/c#).... isto je z neoptimiziranim x86....moj novi 2,4+ ki me je koštal mnogo dinarjev je v buistvu 386.. človek se vpraša če se sploh splača kupt nov komp :)
It's not the opensource i hate.
It's the fanclub I cannot stand.

64202 ::

Hotel sem reci, da zadnji krik mode c# nima nic vec (kvecjemu manj), kot jeziki iz '60/'70. LISP, smalltalk, ML, prolog, anyone?

P4 in AMDji so v bistvu zive umetnine, prakticno noben ni verjel, da se bo dalo z x86 naredit tako hitre procesorje. Splosno gledano so celo med najhitrejsimi nasploh. Edino poraba stroma je porazna, kar pomeni da niso uporabni za zelo velike clustre.

hatch ::

Owca.. ocitno nimas kaj prida izkusenj s programiranjem.

Namrec ce si naredil napako v designu programa in si kot prvo naredil napacen tip spremenljivke (naprimer int namesto unsigned int) potem moras takoalitko preverit vse, kjer se ta spremenljivka uporablja.. in med tem zamenjas tudi ime.

naprimer..
printf("%d", uiCount); bo pac deloval napacno.. moras popravit na
printf("%u", uiCount);

Se en trik.. ubistvu zamenjas ime samo pri deklaraciji.. in potem klikas po compile errorjih in sproti preveris pravilno uporabo in popravis ime. Simple.

Vesoljc ::

spodoben editor ima tudi replace funkcijo...
Abnormal behavior of abnormal brain makes me normal...

OwcA ::

Ni nujno napaka, lahko je sprememba specifikacije, kot tudi ni nujno, da se bo vse sesulo (uporaba kakšne zelo generične knjižnice kot je STL tu zelo pomaga). Glede na to, da govorimo o efektivnem pisanju programov, klikanje (kaj če recimo niti nimaš IDE ;)) po, eventuelno tisočerih, sporočilih o napakah ni ravno to.
Kaj pa pri jezikih, ki niso tipsko varni?
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

hatch ::

kaj ima to veze z gnilimi jajci? Priporocam da brises svoj post, ker je off-topic.

hatch ::

Ni nujno napaka, lahko je sprememba specifikacije, kot tudi ni nujno, da se bo vse sesulo (uporaba kakšne zelo generične knjižnice kot je STL tu zelo pomaga). Glede na to, da govorimo o efektivnem pisanju programov, klikanje (kaj če recimo niti nimaš IDE ) po, eventuelno tisočerih, sporočilih o napakah ni ravno to.


Se ne dogaja. Takih tipov spremenljivk, katere so uporabljane 10x+ se ne spreminja. Enostavno se to ne dogaja...

Glede replaca je pa tako.. da ti lahko naredi vec sranja kot koristi.

kopernik ::

hatch:
Bom svojega zbrisal :-)

Ampak sedaj bi moral tudi tvojega. Ker klikanje po errorjih tudi nima nič s stilom kodiranja ... vendar ga ne bom. Upam, da bo tako volk sit in koza cela (zgleda da se vrtiva v začaranem krogu). Za naprej pa priporočam uporabo teme Pritožbe.

CCfly ::

No lepo da se tema C vs C++ nadaljuje na konstruktiven način.

OwcA ::

Se ne dogaja.

Če ti tako rečeš. Sedaj bom mirno spal in lahkih prstov zapisal
m_lpwszErr
:\
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Exilian ::

mah, ko sem delal audio playerja na pluginih (na konc je spilu mp3 in ogg) za maturo (letos).. sm nonstop spreminju tipe spremeljiv.. saj včasih pač ne predvidiš kaj vse boš moral še narest.. sploh če programeraš sam doma.. drugo je če ti šef reče kaj morš narest.... (na konc sm dubu vse pike :))

zard tega sm opustil madžarsko notacijo, čeprov sm jo nazačetku uporabljal...

BTW: pa sploh če pametno izberaš ime spremeljivk se takoj vid kaj je, brez notacije.. pa sploh zakaj je tako pomembno da veš katerega tipa je| tako ali tako si moraš delat zapiske za kaj je uporabljena kakšna spremenljivka, še posebaj če jih imaš tono?
It's not the opensource i hate.
It's the fanclub I cannot stand.

Zgodovina sprememb…

  • spremenilo: Exilian ()

hatch ::

Na pritozbe sem pisal ze nestetokrat.. pa tudi tam brisete moje kritike. Tako da je vseeno.. ali napisem tu in tu zbrisete.. ali pa tam, in tam zbrisete. Zal.

m_lpwszErr
lol? Si resen?
ne vidim zakaj bi to kdajkoli uporabil. Se manj pa zakaj bi tip take spremenljivke spreminjal.

Ampak recimo da imas tak program..

LPWSTR m_lpwszErr;
Logika mi pravi da bi to recimo hipoteticno spremenil na..
LPSTR m_lpszErr;

To pomeni da moras povsod kjer pises v to spremenljivko dodati, oz. odstraniti _T()
In vsak ne-neumen programer bi napisal zato MACRO. In tako je ta spremenljivka dostopana iz samo enega mesta. Oz.. se tam kjer jo beres. Problem spremeniti ime? Ne.

In ne pozabi... s stringi se error handlinga ne dela nikoli! Sele na koncu, ko zelimo izpisati errorje, se konvertirajo error kode v stringe s pomocjo katalogov.

64202 ::

Kaj pa ce server sporoci napako starejsemu klientu? Ja, dobis "Unknown error 39118" :D

Za errorje je najboljse imeti kar oboje, torej tip/stevilko + text od napake. V c-ju zna to zal biti precej pain, namrec sestaviti lepo & smiselno sporocilo on the fly. Recimo:

error(NEK_ERROR, "Zgodila se je napaka pri obdukciji fajla '%s'", fajl)

To je sicer lepo, ampak kaj zdaj z alokacijo rama za error message? Error stack? Staticen buffer? Argh. Mozna resitev (C++):
http://www.boost.org/libs/format/index....

BigWhale ::

Sej ce programiras za windowse ne rabis error handlinga.. ;>

hatch ::

server/client pa sploh odpade za text error message. Zakaj bi posiljal text dolg 100bytov.. ce lahko posljes 2byta?

File z error defini naj bi bil takoalitako isti za server in client.

Drgac pa naredis macro za printanje/storanje error msgjev. Ena varianta je da jih printas sproti.. druga pa da jih filas v error stack. Macro bi se klical kar takole... PUTERROR(ERROR_BLABLA)
Potem ti pa ta macro.. ali pa mogoce funkcija ce imas error stack resolva msg v text obliko.

OwcA ::

Ker očitno množično ni jasno, da je bil navedeni primer cinizem, oznanjam, da je bil primer m_lpwszErr cinizem. Upam, da mi ni treba razložiti še čemu je temu tako.
Otroška radovednost - gonilo napredka.

Vesoljc ::

heh

kaj je z?
Abnormal behavior of abnormal brain makes me normal...

64202 ::

hatch: Okay, bom se enkrat, da bo jasno. Imas instaliranih 100+ klientov. Pa hoces upgradeat server (recimo bugfix, evo mogoce dodat kak nov error message). Preprosto moras poslat nek error od serverja do klienta v obliki texta, ker klient tistih dveh byteov ne razume. Recimo: kljub temu, da IE izpisuje zelo fensi error message-e, ko gre kaj narobe, preprosto ne mora uganit tega: "Hello folx, we are fixing server over weekend, you can send urgent mail to xyz@abc.com".

owca: meni je to jasno :)

Zgodovina sprememb…

  • spremenilo: 64202 ()

noraguta ::

64202 ti mešaš sporočila userju z error handlingom , protokol mora biti enolično in jasno zdefiniran . error handling je namenjen temu da se aplikacija reši iz zdreg ,do katerih prihaja med delovanjem. Obvestila uporabniku pa povsem nekaj drugega. Če bi že imel dinamični error handling bi moral prenesti zraven tudi kodo ,ki servisera napako. v ostalem zadeva nima smisla.
Oziroma bi se zadeva v praksi po parih generacijah sprevrgla v popolen kaos. (za eno in isto napako bi imel par msgjev, etc ... Protokol je treba dognat in ga potem minimalistično realizirat, kakšne stringe potem obesisš na to pa je stvar katalogov.
Pust' ot pobyedy k pobyedye vyedyot!

64202 ::

Ok, IE primer je malo beden. Ampak ravno the point je, da imas za "isto" napako lahko razlicno razlago. Dovolis, da program vseeno nekako pohendla napako, imas pa boljso razlago poleg v messageu. Hec je v tem, da v kodi direktno sistematicno puscas cimvec informacije, pa ti ni potrebno spreminjati protokola zaradi tega. Spremembe protokola so pogosto nemogoce. Tisti opisi napak naj bodo user friendly, tako da ti jih ni sram pokazati tudi userju. Ja, lahko imas neke standardne message, samo clueful uporabniku (sploh pa tebi, ko te kdo vprasa za pomoc), pogosto nic ne pomagajo. Minimalizem je pa bolje prihraniti za IETF standarde, ne pa day-to-day kodo. Razen ce se gres embedded sisteme jasno :).

hatch ::

Jah ne vem.. sam dodajanje error kod ne zahteva spremembe protokola. V najslabsem primeru bo client napisal: unknown error: 0x00E9 in to samo zato ker nima novega kataloga.

En lep primer (boljsi kot si ga dal ti) je Samba. Kjer se stringi errorjev ne posiljajo.. ampak samo koda.
Nasprotje je pa naprimer FTP.. kjer se vse dela s stringi.. tudi ukazi. Ampak string ima tudi posebno stevilko spredaj. In ftp client po tej stevilki identificira error, ne po besedilu. Enako delujeta tudi POP in IMAP.
Sam to je narejeno tako zarad prav posebnih razlogov in potreb.. telnet tunneling naprimer..

CCfly ::

Pošiljanje sporočil namesto kod prek omrežja je najbolj potraten način, ki si ga lahko zamisliš. Širina je draga, pa še ničesar ne pridobiš.

64202 ::

Eh :|

A ni se nikoli nobeden pomislil, da bi imel SVOJ protokol za po mrezi se menit? Vcasih nobeden obstojec ni dovolj. In tistih 100 byteov enkrat na minuto ni nic. In ja, jasno da ne posljes samo stringa, ampak tudi nek unique ID.

noraguta ::

Ma tudi jaz ne vidim velike omejitve v dolžini stringa. razen pri gprs klijentih je še potrebno optimizirat. ampak z veliko lažje je parsati cifro in preverjati pravilnost vnosa , kot pa kakžen niz znakov.oziroma parsanje je le še en moment več ,da povoziš buffer. z katalogi zelo enostavno vršiš kostumizacijo(internacionalizacija pa še kaj bi se našlo ). Keep it simple and stupid.
Pust' ot pobyedy k pobyedye vyedyot!

64202 ::

Array byteov ti ni treba parsat, zato da ga pokazes userju, razen ce si tak srot protokol naredis :). Saj ze skoz govorim, da posljes ID od errorja zraven. Ampak ce posljes se string, ti ni treba zacementirati nefleksibilnega int->string kataloga v programe. Vcasih hoces tudi poslati drugacen reason za isti error code. Prevode se lepo resi z gettext pristopom, torej _("Text v anglescini"), potem pa imas mapping iz angleskega texta v lokalnega. Najslabsi primer je torej, da program pokaze angleski text, ki ga je poslal server, klient ga pa ne zna prevesti. V primeru errorcode-only pa dobis "Unknown error 5874".

Ce uporabljas customised opise napak po celotni kodi od serverja, je to izredno dobra diagnostika, ko gre kaj narobe. Vidis tocno kje in kaj je slo narobe, ne pa samo skop error code. In ni ti treba pregledat 80MB server loga, ampak se to takoj vidi v klientu. Pa upam da je jasno, da ne mores vedno k stranki v Singapur in se z debuggerjem attachat na proces.

Ej matr, cela znanost. Vam verjamem, da se to vecini zdi overkill. Tudi jaz si tega ne predstavljam it recimo v kakem c-ju. V c++ se pa vse to da zelo lepo & type-safe avtomatizirati.

Zgodovina sprememb…

  • spremenilo: 64202 ()


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

C - shranjevanje rezultatov iz baze v array

Oddelek: Programiranje
71134 (833) Randomness
»

Python

Oddelek: Programiranje
202902 (1588) d_DJ
»

C# povezava forma in classa

Oddelek: Programiranje
172120 (1583) Miko55
»

Pointer-ji v C-ju

Oddelek: Programiranje
291683 (1381) rokpok
»

read integer v javi

Oddelek: Programiranje
91297 (1198) kopernik

Več podobnih tem