» »

V kakšnem stilu pišete vašo kodo?

V kakšnem stilu pišete vašo kodo?

««
«
1 / 9
»»

Mavrik ::

The truth is rarely pure and never simple.
  • spremenil: Mavrik ()

FTad ::

Clean Code vprašanje. Sem prebral knjigo od Roberta C. Martina in mi delujejo principi zelo smiselni, saj sem tudi že sam od nekdaj rad stvari imel urejene (ne samo v kodi).
https://www.amazon.com/Clean-Architectu...

Moje vprašanje je, kakšen je vaš stil pisanja kode? Radi razdelite dele celotne kode na majhne metode s smiselnimi imeni in unit testi (kjer je smiselno), ali namečete celotno logiko v metode/procedure/whatever z več kot 100 vrsticami?

Namreč v službi me moj sodelavec (senior programer) sekira, da preveč drobim kodo v manjše metode, češ da koda ni več bralna.

Primer:
metoda send_email() vsebuje podmetodi get_sender() in get_receiver(). Vsaka od podmetod ima za cca 20-30 vrstic kode (ker je pač nekaj logike, kako se določita pošiljatelj in prejemnik).

send_email(
  // neka koda
  sender = get_sender().
  receiver = get_receiver().
  // spet nekaj kode
).


Meni je osebno veliko lažje iskati po kodi v eclipsu, če lahko na hitro vidim zgoraj imenovani metodi, v primeru, da ju rabim kaj spremeniti, kot da bi scrollal po celi send_email() metodi, da najdem, kakšna je logika za določitev pošiljatelja. Pa tudi metoda dela le eno stvar in se enostavno napiše nekaj unit testov zanjo.
Argument sodelavca je, da je nesmiselno dajati ta del kode v manjšo metodo, češ da mora potem klikniti na metodo, da prebere, kako je ta implementirana -> posledično se kode ne da več tekoče brati, saj mora prekiniti branje, ko je treba klikniti na metodo.

Jaz se s tem ne strinjam, ker postanejo metode predolge in ne moreš narediti enostavnih unit testov. Prav tako traja predolgo, preden kaj najdem v tisti kodi.

Kako se vam to zdi? Ne bi se rad kregal s sodelavcem, ker je senior.

Zgodovina sprememb…

  • premaknil od: Mavrik ()

kuall ::

FTad je izjavil:

Namreč v službi me moj sodelavec (senior programer) sekira, da preveč drobim kodo v manjše metode, češ da koda ni več bralna.

Se kar strinjam z njim, da ni pretiravat s številom metod. Pa še delo imaš s tem kreiranjem milijontih metod. Dobra alternativa temu je tale, katero jaz prakticiram že 10 let: vse pustiš v eni veliki metodi in samo razdeliš metodo na dele, vsak dal pa pokomentiraš. Primer:

// Naredi stvar 1
code
code
code (nič praznih vrstic vmes)

// Naredi stvar 2 (1 prazna vrstica med blokoma)
code
code
code (nič praznih vrstic vmes, ker zmanjšajo bralnost, prazne vrstice naj bodo samo med bloki)

// Nafilaj dataset "dt"
code
code
code

Zgodovina sprememb…

  • premaknil od: Mavrik ()

Vanquish ::

Pol pa more to nekdo vzdrzevat al pa reuse kateri del pa doktorira zraven.

Tako, da je na koncu se ogromno duplicate code

Zgodovina sprememb…

  • premaknil od: Mavrik ()

kuall ::

Če bi prišlo do dupliciranja kode narediš nujno novo metodo.
Ni za pretiravat v nobeno smer. Naj bodo metode normalno velike, ne prevelike in ne premajhne.
Ravno za vzdrževat je taka koda razdeljena na bloke veliko lažja.

Zgodovina sprememb…

  • premaknil od: Mavrik ()

techfreak :) ::

Ce rabis funkcijo razdeliti na vec delov, bi bilo precej dobro razmisliti o razdelitvi na vec funkcij. Naceloma sama funkcija naj ne bi delala prevec stvari, kar se sploh pokaze pri pisanju unit testov.

Zgoraj omenjeni primer od FTad je precej smiselno razdeliti, saj ima ocitno vsaka podfunkcija netrivialno logiko.

Zgodovina sprememb…

  • premaknil od: Mavrik ()

kuall ::

Ravno za to se gre, da se da čisto vsako funkcijo razdeliti na več delov ampak programerji kar vse skupaj zmečejo, da ne veš, kje se en del neha in kje se začne drug del. Tu delajo velikansko škodo, ker ne ločijo funkcije na dele in potem je vse bolj nejasno in težko.

Zgodovina sprememb…

  • premaknil od: Mavrik ()

Vanquish ::

kuall je izjavil:

Če bi prišlo do dupliciranja kode narediš nujno novo metodo.
Ni za pretiravat v nobeno smer. Naj bodo metode normalno velike, ne prevelike in ne premajhne.
Ravno za vzdrževat je taka koda razdeljena na bloke veliko lažja.


Kako pa bos vedo kaj je ze napisano in kaj ne? Na koncu vsak svojo napise in imas 4* stvar, ki isto dela.

Prav tako, kako zgledajo code review-i na velikih blokih? Dosti hitreje poteka po manjsih enotah.
Da pa se da nekaj v funkcijo on the fly pa je dobesedno 30s dela, pa se ponavadi je bolj premisljeno napisano.

Pac moje misljenje.

Zgodovina sprememb…

  • premaknil od: Mavrik ()

kuall ::

V bistvu imajo funkcije, ki so uporabljene na več mestih svoje velike nevarnosti in je treba bit pri njih extra previden: ko kaj spremeniš tako funkcijo moraš misliti na VSA mesta, kjer je uporabljena in da bodo vsa tista mesta še naprej pravilno delala. Ni tak enostavno to. Podoben problem je z DLLji: ko tvoj program uporablja DLL ene verzije, en drug uporablja DLL druge verzije, ta DLL pa je v nekem system folderju. Rata hitro cela zbrka, če ne razmišljaš. DLL Hell @ Wikipedia

Zgodovina sprememb…

  • premaknil od: Mavrik ()

BigWhale ::

kuall je izjavil:

FTad je izjavil:

Namreč v službi me moj sodelavec (senior programer) sekira, da preveč drobim kodo v manjše metode, češ da koda ni več bralna.

Se kar strinjam z njim, da ni pretiravat s številom metod. Pa še delo imaš s tem kreiranjem milijontih metod. Dobra alternativa temu je tale, katero jaz prakticiram že 10 let: vse pustiš v eni veliki metodi in samo razdeliš metodo na dele, vsak dal pa pokomentiraš.


Danes sem poleg proceduralnega, objektnega in funkcijskega programiranja spoznal tudi clusterfuck programiranje. Hvala za insight. :)

Zgodovina sprememb…

  • premaknil od: Mavrik ()

Vanquish ::

kuall je izjavil:

V bistvu imajo funkcije, ki so uporabljene na več mestih svoje velike nevarnosti in je treba bit pri njih extra previden: ko kaj spremeniš tako funkcijo moraš misliti na VSA mesta, kjer je uporabljena in da bodo vsa tista mesta še naprej pravilno delala. Ni tak enostavno to. Podoben problem je z DLLji: ko tvoj program uporablja DLL ene verzije, en drug uporablja DLL druge verzije, ta DLL pa je v nekem system folderju. Rata hitro cela zbrka, če ne razmišljaš. DLL Hell @ Wikipedia


Ti to zdaj cisto resno?

Zgodovina sprememb…

  • premaknil od: Mavrik ()

Raptor F16 ::

V neberljivem :)
Leva ... Leva ... leva desna ena dva

korenje3 ::

Jaz pišem kodo v stilu blackbox.

Čim več funkcij, subrutin in properties.

Je najbolj uporaben način, prav tako se da reciklirat del kode.



Prav tako recimo rekurzivnost ne rešujem s for loopi, ampak kar s subrutine stacking.
Univerzalne funkcije dajem pa vedno v poseben class.
i9-12900k; 32GB DDR5-6000 CL36; Nvidia RTX 3080 ti;
Gigabyte Aorus z690 master; Be Quiet Dark Power 12 1000W

Zgodovina sprememb…

  • spremenil: korenje3 ()

smacker ::

FTad ::

kuall je izjavil:

FTad je izjavil:

Namreč v službi me moj sodelavec (senior programer) sekira, da preveč drobim kodo v manjše metode, češ da koda ni več bralna.

Se kar strinjam z njim, da ni pretiravat s številom metod. Pa še delo imaš s tem kreiranjem milijontih metod. Dobra alternativa temu je tale, katero jaz prakticiram že 10 let: vse pustiš v eni veliki metodi in samo razdeliš metodo na dele, vsak dal pa pokomentiraš. Primer:

// Naredi stvar 1
code
code
code (nič praznih vrstic vmes)

// Naredi stvar 2 (1 prazna vrstica med blokoma)
code
code
code (nič praznih vrstic vmes, ker zmanjšajo bralnost, prazne vrstice naj bodo samo med bloki)

// Nafilaj dataset "dt"
code
code
code


S tem se sploh ne strinjam, pravzaprav sodelavec pravi isto kot ti. Na takem načinu pisanja kode, postane metoda dolga 100+ vrstic in dela več kot le eno stvar.

Morda sem podal slab primer ampak ravno tega, kar si napisal, se želim izogniti.

če se vrnem na primer, ki sem ga podal na začetku, bi bilo že dejansko bolje, da se metode napišejo takole:

prepare_and_send_email( parameter ) {
  obj sender = get_sender( parameter ).
  obj receiver = get_receiver( parameter ).
  
  send_email(sender, receiver).
}

method get_sender{
 // koda z 20 vrsticami, kjer assignaš atribute senderju 
}

˙
method send_email{
 // koda z 20 vrsticami
}

meni se zdi tale koda veliko bolj berljiva, kot pa da bi vse nabasal v metodo prepare_and_send_email( ), ki bi potemtakem bila vsaj 60 vrstic (pač nek posplošen primer).

Mene pri branju kode ne zanima, kako se določita sender in receiver, razen, če bi želel debugat kodo.

Dodaten plus je to, da za metodi get_sender in get_receiver spišem kak unit test in je zadeva stestirana.

kuall je izjavil:

V bistvu imajo funkcije, ki so uporabljene na več mestih svoje velike nevarnosti in je treba bit pri njih extra previden: ko kaj spremeniš tako funkcijo moraš misliti na VSA mesta, kjer je uporabljena in da bodo vsa tista mesta še naprej pravilno delala. Ni tak enostavno to. Podoben problem je z DLLji: ko tvoj program uporablja DLL ene verzije, en drug uporablja DLL druge verzije, ta DLL pa je v nekem system folderju. Rata hitro cela zbrka, če ne razmišljaš. DLL Hell @ Wikipedia


Nevarno je samo, če uporabjaš kake util classe, ki si ga napisal v enem paketu, uporabljaš ga pa vsepovprek. Če je ta util metoda znotraj paketa in se jo uporablja le v klasih znotraj le tega, to naj ne bi predstavljalo problema.

Zgodovina sprememb…

  • spremenil: FTad ()

DePalmo ::

Odvisno. Včasih je moja koda dolga kot špaget, včasih pa razdelim na smiselne dele, odvisno kaj natančno hočem. Če je kakšna funkcija dolga in vem da določenih podfunkcij ne bom uporabil nikjer drugje, je pač en dolg špaget. Če pa vem da bom del kode uporabljal še drugje, pa vedno spišem samostojne funkcije.

A vi uporabljate "get_sender" in "get_receiver" ali je to samo primer? Ker jaz imam pač spisano svojo metodo ki skompajla email, podaš pa: komu, (od koga se določi vnaprej z nastavitvijo aplikacije), zadeva, vsebina (ponavadi html, text se generira s pluginom), priponke in to je to. Funkcija seveda še shrani email na disk in če je bil uspešno poslan ali ne.

Me pa osebno bolj zanima (mogoče stvar nove teme?) kako natančno pišete unit in function teste. A gledate da je json response specifičen do vsakega znaka posebi, ali da pač vrne 200 in po možnosti še prave attribute in je to to?

WhiteAngel ::

FTad je izjavil:


Argument sodelavca je, da je nesmiselno dajati ta del kode v manjšo metodo, češ da mora potem klikniti na metodo, da prebere, kako je ta implementirana -> posledično se kode ne da več tekoče brati, saj mora prekiniti branje, ko je treba klikniti na metodo.

Jaz se s tem ne strinjam, ker postanejo metode predolge in ne moreš narediti enostavnih unit testov. Prav tako traja predolgo, preden kaj najdem v tisti kodi.


Odvisno tudi od tega ali bo še kdo drug klical metodo oz. jo bi tudi ti večkrat klical znotraj tvoje funkcije. Če ne, potem jaz ne vidim smisla v drobljenju. Lahko narediš tudi anonimen blok v kodi, da ne smetiš po preostanku funkcije z novimi spremenljivkami:
void something() {
  int a=42;
  int b=7;
  {
      int c=a/b;
      printf("%d", c);
  }
  // Od tu naprej c ni vec dosegljiv.

WhiteAngel ::

FTad je izjavil:


S tem se sploh ne strinjam, pravzaprav sodelavec pravi isto kot ti. Na takem načinu pisanja kode, postane metoda dolga 100+ vrstic in dela več kot le eno stvar.

Morda sem podal slab primer ampak ravno tega, kar si napisal, se želim izogniti.

če se vrnem na primer, ki sem ga podal na začetku, bi bilo že dejansko bolje, da se metode napišejo takole:


prepare_and_send_email( parameter ) {
obj sender = get_sender( parameter ).
obj receiver = get_receiver( parameter ).

send_email(sender, receiver).
}

method get_sender{
// koda z 20 vrsticami, kjer assignaš atribute senderju
}

˙
method send_email{
// koda z 20 vrsticami
}



Bi se kar strinjal s sodelavcem v zgornjem primeru. Ko nekaj debuggiramo in na hitro beremo kodo, jo beremo ne samo po celotno vrstico naenkrat, ampak tudi po več vrstic hkrati. Takle get_sender() klic vmes, ki je bistven za prepare_and_send(), te upočasni s skakanjem, ko to počneš. Tudi odločiti se moraš, ali boš sploh šel v get_sender() funkcijo iskat bug, ali ji boš zaupal, da deluje, in iskal dalje v prepare_and_send(). To govorim seveda za primer, ko se get_sender() samo iz prepare_and_send() kliče in to natanko enkrat. V nasprotnem primeru narediš ločeno get_sender() funkcijo, da se ti koda ne podvaja, valda.

kuall ::

FTad je izjavil:

S tem se sploh ne strinjam, pravzaprav sodelavec pravi isto kot ti. Na takem načinu pisanja kode, postane metoda dolga 100+ vrstic in dela več kot le eno stvar.


Če je koda tako zakomplicirana, da moraš delat za njo unit teste, potem naredi novo metodo iz nje.
Metoda naj naredi samo eno stvar. SendMail() naj pošlje samo email, komu pa naj ima v argumentih.
To je vse common sense.

Če imaš po drugi strani metodo za uvoz naročil iz jsona ni noben problem, če je dolga 1000 vrstic. Lahko bi jo drobil na podmetode naredi_glavo(), naredi_pozicije() ampak je to brezveze, samo težje bi bilo brati. Popolnoma nobene dodatne vrednosti ne bi pridobil. Verjamem pa, da veliko ljudi drobi take metode, ker so nekje prebrali, da so 1000 vrstic dolge metode zlo. :D

Zgodovina sprememb…

  • spremenilo: kuall ()

SloKin ::

FTad je izjavil:



prepare_and_send_email( parameter ) {
obj sender = get_sender( parameter ).
obj receiver = get_receiver( parameter ).

send_email(sender, receiver).
}

method get_sender{
// koda z 20 vrsticami, kjer assignaš atribute senderju
}

˙
method send_email{
// koda z 20 vrsticami
}

Napiši mu celotno kodo v eni funkciji. Podaj spremenljivkam nesmiselna imena. Vmes vtakni še kakšen macro in kakšen include. Seveda ne smeš napisati dokumentacije, če pa jo napišeš naj bo v polomljeni angleščini z mešanico nemščine ali španščine in naj bo opis neke popolnoma random metode. Potem ga pa vprašaj, če se mu zdi bolje. Precej bolj pametni ljudje, od tvojega senilnega seniorja, pišejo kodo v majhnih funkcijah. Razlogov je več: debugging, documentation, testing, reusability, profiling, refactoring, adapt to change,... Če on ne more slediti programu potem ni senior developer.

kuall je izjavil:

V bistvu imajo funkcije, ki so uporabljene na več mestih svoje velike nevarnosti in je treba bit pri njih extra previden: ko kaj spremeniš tako funkcijo moraš misliti na VSA mesta, kjer je uporabljena in da bodo vsa tista mesta še naprej pravilno delala.

Ti buga v libu ne bi popravil, ker nekomu tam zunaj njegova skripta za vdor ne bo delovala pravilno.
Ravno v prevelikih funkcijah tvoj problem. Eno stvar spremeniš v svoji megalomanski funkciji in si kot slon v trgovini s porcelanom. In ne... Delitev na sklope znotraj funkcije ni primerna rešitev. Zato so funkcije...

SloKin ::

kuall je izjavil:


Če je koda tako zakomplicirana, da moraš delat za njo unit teste, potem naredi novo metodo iz nje.
Metoda naj naredi samo eno stvar. SendMail() naj pošlje samo email, komu pa naj ima v argumentih.
To je vse common sense.

Če imaš po drugi strani metodo za uvoz naročil iz jsona ni noben problem, če je dolga 1000 vrstic. Lahko bi jo drobil na podmetode naredi_glavo(), naredi_pozicije() ampak je to brezveze, samo težje bi bilo brati. Popolnoma nobene dodatne vrednosti ne bi pridobil. Verjamem pa, da veliko ljudi drobi take metode, ker so nekje prebrali, da so 1000 vrstic dolge metode zlo. :D

Heh... če za metodo rabiš unit test potem naredi novo metodo. Super rekurzija nimaš kaj.
SendMail sprejme sender in receiver. Preberi še enkrat...
Kar se tiče glave in pozicije. Še ena cvetka. Če mi program ne deluje pravilno in vem, da je problem v glavi se bom osredotočil na funkcijo za glavo. Če vem, da je v poziciji problem se bom osredotočil na tisto funkcijo. V nasprotnem primeru bom moral naštudirat popolnoma vse kar se zgodi v funkciji.

mr_chai ::

Ja če mate že tok radi OO, zakaj ga ne uporabljate.


method create-email(params as p) {
new Email(sender: p.sender, receiver: p.receiver, body: p.body)
}

method send-email(email) {
some.lib.for.smtp.send(email);
}

// some other file
method my-business-logic(params) {
email = create-email(params)
send-email(email) // or whatever..
}

Če je pa logika za kreiranje senderja in receiverja zakomplicirana, pa nardiš še posebej metodi create-sender in create-receiver... Plus te rešitve je, da lahko pol unit testaš, če se ti emaili pravilno zgenerirajo, brez da bi rabu email kam pošiljat. Torej kreiranje in pošiljanje mailov se decoupla, al kako že ta stric Bob (ki je btw, za mene en šarlatan) to imenuje..

Zgodovina sprememb…

  • spremenilo: mr_chai ()

Uporabnik ::

V lastnem stilu :)
If You Don\'t Stand for Something, You\'ll Fall for Anything

kuall ::

>Heh... če za metodo rabiš unit test potem naredi novo metodo. Super rekurzija nimaš kaj.
Površno bereš.

>SendMail sprejme sender in receiver. Preberi še enkrat...
Takle je najbolj pravilni način, če mene vprašaš:
prepare_and_send_email( parameter ) {

  // Get "sender".
  20 vrstic kode

  // Get "receiver".
  20 vrstic kode
  
  // Now send email.
  send_email(sender, receiver).
}



>V nasprotnem primeru bom moral naštudirat popolnoma vse kar se zgodi v funkciji.
Ni treba popolnoma vse študirat. Če kodo deliš po blokih, tako kot sem prej svetoval samo scrollaš do bloka
// Kreiraj pozicije
in gledaš samo tisti blok.
Medtem ko če bi delal novo metodo kreiraj_pozicije () bi imela polno argumentov, kar bi ti vzelo kar nekaj časa vse argumente natipkat in je samo zguba časa brez dodane vrednosti. Da ne omenjamo, da moraš skakat gor in dol, ne moreš kode brati neprekinjeno tako, kot se izvaja.

SloKin ::

kuall je izjavil:



prepare_and_send_email( parameter ) {

// Get "sender".
20 vrstic kode

// Get "receiver".
20 vrstic kode

// Now send email.
send_email(sender, receiver).
}



>V nasprotnem primeru bom moral naštudirat popolnoma vse kar se zgodi v funkciji.
Ni treba popolnoma vse študirat. Če kodo deliš po blokih, tako kot sem prej svetoval samo scrollaš do bloka
// Kreiraj pozicije
in gledaš samo tisti blok.
Medtem ko če bi delal novo metodo kreiraj_pozicije () bi imela polno argumentov, kar bi ti vzelo kar nekaj časa vse argumente natipkat in je samo zguba časa brez dodane vrednosti. Da ne omenjamo, da moraš skakat gor in dol, ne moreš kode brati neprekinjeno tako, kot se izvaja.

Aha in na vrhu ti deklariram int i = 0; Kje vse sem ga uporabil v tvojih 1000 vrsticah?

kuall ::

"i" je itak neprimerno ime za spremenljivko.

SloKin ::

kuall je izjavil:

"i" je itak neprimerno ime za spremenljivko.

Pa greva še naprej. Logika za izračun sender-ja se je spremenila. Bo šlo to đabe popravit? Kaj vse bomo morali pretestirat? Joj zdaj bi pa še receiver-ja spremenili. Kaj vse moramo pretestirat? Bomo pošiljali 1000 mailov?

Oh kuall. A če jo poimenujem str, bo bolje? Ej kako pa vem v 1000 vrstici, da moj str še ni bil uporabljen? Bom naštudiral 1000 vrstic po tvoje?

kuall ::

Saj sem rekel, če je koda za "get sender" tako komplicirana, da jo moraš testirat pa kreiraj svojo funkcijo iz nje, ti noben ne brani. Ponavadi tak blok ni tako kompliciran, da bi ga moral posebej testirat.
Pri tistem drugem primeru za kreiranje pozicije naročila vsekakor ne mislim tistega dela za kreiranje pozicij samostojno testirat, ker je breveze. Če kaj narobe dela bom stestiral uvoz celotnega naročila, bo lažje.

Jaz sem napisal eno tako mega funkcijo s 1000 vrsticami za uvoz naročil iz jsona in dela brezhibno od prvega dne. Danes sem moral eno malenkost dodelat (ne popravit) in ni bil čisto noben problem. Še lažje je bilo, ker je samo 1 funkcija, ker sem lahko celo funkcijo pregledal kako se izvaja, mi ni bilo treba skakat po podfunkcijah. Sem pa tudi opazil mimogrde, da je firma v 1 letu naredila za milijone eur naročil, medtem ko sem jaz dobil samo par sto eurov za ta uvoz, jebemti. Premalo jim računamo.

Testiramo, ampak testira se glavno funkcijo, ne pa podfunkcij. Če ti je podfunkcija zajebana jo seveda stestiraš vmes ko programiraš.

Zgodovina sprememb…

  • spremenilo: kuall ()

SloKin ::

kuall je izjavil:

Saj sem rekel, če je koda za "get sender" tako komplicirana, da jo moraš testirat pa kreiraj svojo funkcijo iz nje, ti noben ne brani. Ponavadi tak blok ni tako kompliciran, da bi ga moral posebej testirat.
Pri tistem drugem primeru za kreiranje pozicije naročila vsekakor ne mislim tistega dela za kreiranje pozicij samostojno testirat, ker je breveze. Če kaj narobe dela bom stestiral uvoz celotnega naročila, bo lažje.

Aja vi ne testirate kode, ko jo daste v produkcijo? Ko kaj spremenite ne naredite test? Bam v produkcijo pa če gredo milijoni pač gredo...

mr_chai ::

SloKin je izjavil:


Pa greva še naprej. Logika za izračun sender-ja se je spremenila. Bo šlo to đabe popravit? Kaj vse bomo morali pretestirat? Joj zdaj bi pa še receiver-ja spremenili. Kaj vse moramo pretestirat? Bomo pošiljali 1000 mailov?


Tle mi nekaj smrdi. Logika za izračun senderja, se ne dela tam kjer se pošiljajo maili. Malo več podatkov o samem problemu bi potrebovali, da bi ti lahko svetovali kako se problema lotiti. Sklepam, da tvoja get_sender in get_receiver šarita po bazi in glede na neko stanje v bazi grupiraš senderje oz receiver ali kaj točno se dela ?

ajdov ::

if it was hard to write it should be hard to read

napsy ::

Taksne teme so mi vsec, ker obicajno vsi vemo, kako bi morala biti napisana koda :) v resnicnosti pa je dostikrat drugace :).

Ce se ne mudi, si obicajno vzamem cas in napisem cim bolj testable kodo: interfejse kjer je treba, pure functions ce lahko, skupaj pokrito s testi. V industriji pa se (vecinoma?) mudi in tudi jaz kdaj pregresim. V idealnem okolju bi morala biti tut koda pokomentirana pa mi dostikrat ne rata oz. so neki minimalni komentarji.
"If you die, you die. But when you live you live. There is no time to waste."

JanBrezov ::

Odvisno. Blok kode (funkcije, procedure..) naj bo praviloma takšne dolžine, da je vidna v celoti na zaslonu (pa ne bi o ekstremnih konfiguracijah zaslonov). Če ne gre na zaslon, razbiješ na funkcije, če to gre (običajno gre). Kot so že omenili, kratke neodvisne funkcije lažje unittestaš kot dolge in so lažje razumljive. Dodal bi še to: krajša, kot je funkcija, krajša imena spremenljivk lahko uporabiš. Spremenljivka "i" je popolnoma ok ime spremenljivke, če gre za funkcijo z eno samo zanko, ki ima par vrstic kode. Kratke funkcije običajno delajo na malem številu spremenljivk in je bolj ali manj očitno, kaj spremenljivke so. Poleg tega funkcije omejujejo doseg spremenljivk (scope), kar je stvar, kar je v daljši kodi lahko hitro problem. Imam oba scenarija kode v mojih projektih, a sem začel prehajati na kratke funkcije, ker se mi enostavno zdi bolj berljivo.

ajdov je izjavil:

if it was hard to write it should be hard to read

Ne! Če nekaj rešuješ, reši za vse. Če tako razmišljaš, očitno nisi team player, si pa asshole.

Invictus ::

Stil kodiranja je tak kot je predpisan v firmi...

Seveda, če ga kdo napiše ;).
"Life is hard; it's even harder when you're stupid."

http://goo.gl/2YuS2x

FTad ::

DePalmo je izjavil:

Odvisno. Včasih je moja koda dolga kot špaget, včasih pa razdelim na smiselne dele, odvisno kaj natančno hočem. Če je kakšna funkcija dolga in vem da določenih podfunkcij ne bom uporabil nikjer drugje, je pač en dolg špaget. Če pa vem da bom del kode uporabljal še drugje, pa vedno spišem samostojne funkcije.

A vi uporabljate "get_sender" in "get_receiver" ali je to samo primer? Ker jaz imam pač spisano svojo metodo ki skompajla email, podaš pa: komu, (od koga se določi vnaprej z nastavitvijo aplikacije), zadeva, vsebina (ponavadi html, text se generira s pluginom), priponke in to je to. Funkcija seveda še shrani email na disk in če je bil uspešno poslan ali ne.

Me pa osebno bolj zanima (mogoče stvar nove teme?) kako natančno pišete unit in function teste. A gledate da je json response specifičen do vsakega znaka posebi, ali da pač vrne 200 in po možnosti še prave attribute in je to to?



To je samo primer. Mogoče malo slab, ker si pri get_sender, get_receiver verjetno predstavljamo samo, da ti vrne email naslov.

WhiteAngel je izjavil:

FTad je izjavil:


S tem se sploh ne strinjam, pravzaprav sodelavec pravi isto kot ti. Na takem načinu pisanja kode, postane metoda dolga 100+ vrstic in dela več kot le eno stvar.

Morda sem podal slab primer ampak ravno tega, kar si napisal, se želim izogniti.

če se vrnem na primer, ki sem ga podal na začetku, bi bilo že dejansko bolje, da se metode napišejo takole:


prepare_and_send_email( parameter ) {
obj sender = get_sender( parameter ).
obj receiver = get_receiver( parameter ).

send_email(sender, receiver).
}

method get_sender{
// koda z 20 vrsticami, kjer assignaš atribute senderju
}

˙
method send_email{
// koda z 20 vrsticami
}



Bi se kar strinjal s sodelavcem v zgornjem primeru. Ko nekaj debuggiramo in na hitro beremo kodo, jo beremo ne samo po celotno vrstico naenkrat, ampak tudi po več vrstic hkrati. Takle get_sender() klic vmes, ki je bistven za prepare_and_send(), te upočasni s skakanjem, ko to počneš. Tudi odločiti se moraš, ali boš sploh šel v get_sender() funkcijo iskat bug, ali ji boš zaupal, da deluje, in iskal dalje v prepare_and_send(). To govorim seveda za primer, ko se get_sender() samo iz prepare_and_send() kliče in to natanko enkrat. V nasprotnem primeru narediš ločeno get_sender() funkcijo, da se ti koda ne podvaja, valda.


Jaz bi osebno raje dal oba dela v posebej funkciji, da ko odprem kodo po treh mesecih, hitro najdem, na katerem mestu sem že implementiral ta del. Če bi bila ena sama metoda npr prepare_and_send dolga 200 vrstic, pa na začetku le te še nekaj pripravimo (npr convert_attachemnt_to_binary ipd), pa ti že to nanese nekaj vrstic, potem pa še nekaj vmes in nato nekje na sredini določim senderja in receiverja, mi več časa pobere, da najdem, kje na sredini metode sem že do določil, kot pa da imam to ločeno v eni metodi, kljub temu, da se samo kliče enkrat v celotnem programu.

Zgodovina sprememb…

  • spremenil: FTad ()

bbbbbb2015 ::

FTad je izjavil:

Clean Code vprašanje. Sem prebral knjigo od Roberta C. Martina in mi delujejo principi zelo smiselni, saj sem tudi že sam od nekdaj rad stvari imel urejene (ne samo v kodi).
https://www.amazon.com/Clean-Architectu...

Moje vprašanje je, kakšen je vaš stil pisanja kode? Radi razdelite dele celotne kode na majhne metode s smiselnimi imeni in unit testi (kjer je smiselno), ali namečete celotno logiko v metode/procedure/whatever z več kot 100 vrsticami?

Namreč v službi me moj sodelavec (senior programer) sekira, da preveč drobim kodo v manjše metode, češ da koda ni več bralna.
Jaz se s tem ne strinjam, ker postanejo metode predolge in ne moreš narediti enostavnih unit testov. Prav tako traja predolgo, preden kaj najdem v tisti kodi.

Kako se vam to zdi? Ne bi se rad kregal s sodelavcem, ker je senior.


Tvoje vprašanje je zelo subjektivne narave. Osebno pišem module, ki so do 2000 vrstic dolgi, metode pa do 300-400 vrstic, nekatere do 1000 vrstic. Posamezne vrstice so do 180 znakov dolge, kar smo s sodelavci povečali iz prejšnjih 130 vrstic, kar pa smo povečali iz 80 vrstic.

Vsi (vsaj večina) imamo tri ekrane (sedaj imam enega 4K 27'' in dva pokonci postavljena HD 24'') in delamo (večina) v IDEA IntelliJ, nekateri tudi v Eclipse(u).

Uporabljamo code formatting in je dogovor, da je koda sformatirana, preden se naredi komit (česar pa se ne držijo vsi), za kodo pa uporabljamo SonarQube,oz. jaz imam v IntelliJ en standalone modul, ki on the fly preveri kodo.

Tako kot je, smo zadovoljni vsi, je pa stvar dogovora, kaj je sprejemljiva koda. Npr., ta koda, o kateri govorim, je popolnoma neobvladljiva na enem 13 colskem laptopu. Tudi na 15.4'' laptopu je težko delati, razen če imaš 4K ekran in dobre oči.

Sem pa prej delal v tim,u, kjer smo vsi imeli en 24'' HD ekran, tam smo imeli limit dolžine modula do 1000 vrstic in dolžino vrstice do 130 znakov.

Tako da je zelo odvisno, s kakšnim harverom delaš.

Vanquish ::

se ti resnicno zdi, da bi moglo to bit odvisno od velikosti ekrana?

SloKin ::

mr_chai je izjavil:


Tle mi nekaj smrdi. Logika za izračun senderja, se ne dela tam kjer se pošiljajo maili. Malo več podatkov o samem problemu bi potrebovali, da bi ti lahko svetovali kako se problema lotiti. Sklepam, da tvoja get_sender in get_receiver šarita po bazi in glede na neko stanje v bazi grupiraš senderje oz receiver ali kaj točno se dela ?

Več stvari ti smrdi. Ena izmed teh je, da sprašuješ napačno osebo o use casu. Nisem jaz zastavil vprašanja...
OP je zastavil stvar tako, da ima parameter preko katerega dobi senderja in receiverja. Kaj je s tem narobe? Tako delajo vsi avtomatski procesi. Kuall nas uči, da je bolje, če zadevo zapiše v eni funkciji. Nekaj argumentov smo slišali. Funkcijo mora parametrizirat in težko sledi kodi. Koliko več parametrov bi moral imeti je seveda odvisno od use casa ampak defitnivno ni tako veliko, da bi bil to razlog za opustitev uporabe funkcije. Nad drugim argumentom se bo moral pa zamislit, če ima težave s sledenjem funkcije z imenom get_sender. Verjetno funkcija vrne povprečno plačo zaposlenega v podjetju.

bbbbbb2015 je izjavil:


Tvoje vprašanje je zelo subjektivne narave. Osebno pišem module, ki so do 2000 vrstic dolgi, metode pa do 300-400 vrstic, nekatere do 1000 vrstic. Posamezne vrstice so do 180 znakov dolge, kar smo s sodelavci povečali iz prejšnjih 130 vrstic, kar pa smo povečali iz 80 vrstic.

Vsi (vsaj večina) imamo tri ekrane (sedaj imam enega 4K 27'' in dva pokonci postavljena HD 24'') in delamo (večina) v IDEA IntelliJ, nekateri tudi v Eclipse(u).

Uporabljamo code formatting in je dogovor, da je koda sformatirana, preden se naredi komit (česar pa se ne držijo vsi), za kodo pa uporabljamo SonarQube,oz. jaz imam v IntelliJ en standalone modul, ki on the fly preveri kodo.

Tako kot je, smo zadovoljni vsi, je pa stvar dogovora, kaj je sprejemljiva koda. Npr., ta koda, o kateri govorim, je popolnoma neobvladljiva na enem 13 colskem laptopu. Tudi na 15.4'' laptopu je težko delati, razen če imaš 4K ekran in dobre oči.

Sem pa prej delal v tim,u, kjer smo vsi imeli en 24'' HD ekran, tam smo imeli limit dolžine modula do 1000 vrstic in dolžino vrstice do 130 znakov.

Tako da je zelo odvisno, s kakšnim harverom delaš.


Noro kaj vse doživiš... Že iz samega dejstvo, da rabiš 180 znakov v vrstici mi daje mislit, da je koda neberljiva. Java? Pismo še select stavek se razbije v več vrstic...
Zakaj mora ta sektor vedno znova odkrivat neko znanost? Kot, da pred računalnikom svet ni obstajal:
For best legibility, typographic manuals suggest that columns should be wide enough to contain roughly 60 characters per line.

Invictus ::

Vanquish je izjavil:

se ti resnicno zdi, da bi moglo to bit odvisno od velikosti ekrana?

Prazaprav ja...

80 znakov na vrstico je predpotopno...

Danes imaš lahko več znakov, sam imam po terminalih 150-200 znakov široko vrstico.

Kateri razvijalec pa ima manj kot 25" inčni ekran?
"Life is hard; it's even harder when you're stupid."

http://goo.gl/2YuS2x

RedDrake ::

Točno to kar pravi b..2015.
Vse je odvisno od HW in od dogovora v teamu oziroma zahtev naročnika (če jih ima) in ali naročnik planira uporabljati tudi druge ljudi kasneje za razvoj kode.

Osebno večino stvari ne delam v teamu, posledično je koda dostikrat objektivno gledano neberljiva. Mislim da imam celo nekje (v "produkciji") en program, kjer je main dobesedno par tisoč vrstic in ni nobenih drugih funkcij (C btw).
Jasno, kadar delam za druge, so stvari "lepo" razbite in dokumentirane. Tipično bom vsak del kode, ki se mi kjerkoli ponovi dal v lastno funkcijo v nekem smiselnem okvirju.
@SloKin:
Evo ti eno "dolgo vrstico". (EDIT, vidim da st.koda ni najboljša opcija ...)
ws.Cells[alphabet[alphabetOffset] + (headerOffset + entryNumber).ToString()].Value = milivoltsToTemp(bytesToMilivolts(channelRawByteValues[enabledSamples[sampleNumber].channel[channelNumber]][entryNumber]));

Zgodovina sprememb…

  • spremenil: RedDrake ()

RedDrake ::

Invictus je izjavil:

Vanquish je izjavil:

se ti resnicno zdi, da bi moglo to bit odvisno od velikosti ekrana?

Prazaprav ja...

80 znakov na vrstico je predpotopno...

Danes imaš lahko več znakov, sam imam po terminalih 150-200 znakov široko vrstico.

Kateri razvijalec pa ima manj kot 25" inčni ekran?

Jaz sem do pred kratkim vse razvijal na 14" HD+ (1600x900) v vim-u.
b.p., če nisi ravno codemonkey. Sem malo nadgradil sedaj, ja.
Ampak če ne uporabljaš IDE ne rabiš strašno velikih ekranov.
IDE pa požre screen real-estate prej kot rečeš keks, se strinjam.

SloKin ::

RedDrake je izjavil:


@SloKin:
Evo ti eno "dolgo vrstico". (EDIT, vidim da st.koda ni najboljša opcija ...)
ws.Cells[alphabet[alphabetOffset] + (headerOffset + entryNumber).ToString()].Value = milivoltsToTemp(bytesToMilivolts(channelRawByteValues[enabledSamples[sampleNumber].channel[channelNumber]][entryNumber]));

Pa nam prosim razjasni zakaj je to bolje v eni vrstici kot v večih.

BigWhale ::

kuall je izjavil:

Saj sem rekel, če je koda za "get sender" tako komplicirana, da jo moraš testirat pa kreiraj svojo funkcijo iz nje, ti noben ne brani.
...
...
Testiramo, ampak testira se glavno funkcijo, ne pa podfunkcij. Če ti je podfunkcija zajebana jo seveda stestiraš vmes ko programiraš.


Men se zdi, da tebi ni povsem jasno zakaj se pise teste, kaj se s testi testira in zakaj se sploh testira.

Neke funkcije med razvojem enostano ne mores stestirati in rect, da zdej bo pa delala dokler ne nastopi heat death of the universe. Teste se pise zato, da so ti v pomoc pri refaktoriranju in pri spremembah v kodi.

RedDrake ::

SloKin je izjavil:


Pa nam prosim razjasni zakaj je to bolje v eni vrstici kot v večih.

Ni razloga. Tako je pač bilo napisano.

BigWhale je izjavil:


Men se zdi, da tebi ni povsem jasno zakaj se pise teste, kaj se s testi testira in zakaj se sploh testira.
Neke funkcije med razvojem enostano ne mores stestirati in rect, da zdej bo pa delala dokler ne nastopi heat death of the universe. Teste se pise zato, da so ti v pomoc pri refaktoriranju in pri spremembah v kodi.

90% časa se nameni analizi, pripravi razvojne dokumentacije (funkcionalni diagrami, kontekstni diagrami, podatkovni tokovi, če so baze jasno ER, ipd ...). 10% časa pa potem code monkey pretipkava ta dokument, ki je tipično nekaj 100 strani v poljuben IDE.
A ne delate tako?
You're doing it wrong then ...

win64 ::

In kako testiraš, da si pravilno pripravil dokumentacijo?
Kako testiraš, da je koda pravilno "pretipkana"? Da se pravilno preverja vhodne podatke..

bbbbbb2015 ::

SloKin je izjavil:

Noro kaj vse doživiš... Že iz samega dejstvo, da rabiš 180 znakov v vrstici mi daje mislit, da je koda neberljiva. Java? Pismo še select stavek se razbije v več vrstic...
Zakaj mora ta sektor vedno znova odkrivat neko znanost? Kot, da pred računalnikom svet ni obstajal:
For best legibility, typographic manuals suggest that columns should be wide enough to contain roughly 60 characters per line.


Zdaj, če iz muzeja nekaj potegneš, še ne pomeni, da je dobro za današnji čas (2020) ali sploh za vekomaj.

Jaz sem programiranje začel na IskraDelta klonu DEC terminala, ki je bil 80x25 ali nekaj takega. Že skrolanje na desno je bila moteča operacija, kaj šele skok na določene vrstice.

Tako da vem, kaj pomeni biti limitiran.
Načeloma pa IDEji zmorejo ogromno, z miško pokažeš, syntax coloring, on-the fly sintaktična, semantična in lepotna analiza (SonarQ). Dolgo časa sem kodo razvijal na dual-core Intelu in kar sem razvijal, je IDE držal obe jedri na 70-100% zasedenosti. Zdaj delam na 4-core (8 HT) in samo razvijanje drži CPU na 65-100% utilizacije.

In če je tako, potem ima smisel real-estate ekranov izkoristiti do konca.

Seveda, kot sem rekel, to isto je precej slabše obladljivo na enem ekranu. To pa je že stvar tima, naročnika in dogovora med razvijalci.

Zgodovina sprememb…

sreda ::

Spremenljivka i
priporočam uporabljati namesto i ja da se uporablja ii

Mnogo bolj praktično, ko je treba iskat po kodi.

secops ::

sreda je izjavil:

Spremenljivka i
priporočam uporabljati namesto i ja da se uporablja ii

Mnogo bolj praktično, ko je treba iskat po kodi.


A ti v notepadu programiraš?

Invictus ::

win64 je izjavil:

In kako testiraš, da si pravilno pripravil dokumentacijo?
Kako testiraš, da je koda pravilno "pretipkana"? Da se pravilno preverja vhodne podatke..

Temu se reče review designa in unit testi...
"Life is hard; it's even harder when you're stupid."

http://goo.gl/2YuS2x

win64 ::

Invictus je izjavil:

win64 je izjavil:

In kako testiraš, da si pravilno pripravil dokumentacijo?
Kako testiraš, da je koda pravilno "pretipkana"? Da se pravilno preverja vhodne podatke..

Temu se reče review designa in unit testi...

Da, samo zgoraj trdi, da unit testi niso potrebni za testiranje sprememb v kodi, če imaš odlično dokumentacijo.
««
«
1 / 9
»»


Vredno ogleda ...

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

Python najbolj vroč programski jezik (strani: 1 2 3 )

Oddelek: Novice / Ostala programska oprema
12229135 (23489) BigWhale
»

Unit testing - se poslužujete?

Oddelek: Programiranje
335178 (3328) krneki0001
»

Applov nov programski jezik Swift (strani: 1 2 )

Oddelek: Novice / Apple iPhone/iPad/iPod
7234344 (28905) Kocka
»

Incident Knight Capital in slaba programska oprema, ki poganja svet

Oddelek: Novice / Znanost in tehnologija
4715447 (12354) Poldi112
»

Odkrit resen hrošč v PHP 5.3.7 (strani: 1 2 )

Oddelek: Novice / Varnost
5016996 (14763) Spura

Več podobnih tem