Kommentit
Vastaa
Jos jatkan kun kirjoitat lisää koodia, silloin on aika, jolloin minun on vaikea järjestää koodia.
Tämä on ongelmasi: saat organisaation oikein, ja tyylin pitäisi liikkua helpommin.
Älä ”odota järjestäessäsi koodiasi: pidä koodi järjestyksessä mennessäsi. Vaikka kieli ei tee sitä puolestasi, koodi tulisi silti järjestää moduuleiksi, joilla on matala kytkentä ja korkea koheesio.
Nämä moduulit tarjoavat luonnollisesti nimitilan. Lyhennä moduulin nimi (jos se on pitkä) ja etuliittele funktioiden nimet moduuliinsa törmäysten välttämiseksi.
Yksilöllisten tunnisteiden tasolla nämä ovat karkeasti kasvamassa subjektiivisuuden järjestyksessä:
- valitse käytäntö ja pidä siitä kiinni
- esim.
function_like_this(struct TypeLikeThis variable)
on yleinen
- esim.
-
välttele ehdottomasti unkarilaisia merkintöjä (anteeksi JNL)
-
ellet halua käyttää sitä alun perin tarkoitetulla tavalla, mikä tarkoittaa Simonyin sovellusten merkintää eikä kauhea järjestelmäversio
Miksi? Voisin kirjoittaa tästä esseen, mutta ehdotan sen sijaan, että luet tämän artikkelin Joel Spolsky, ja sitten metsästää lisää, jos olet kiinnostunut. Alareunassa on linkki Simonyin alkuperäiseen paperiin.
-
-
vältä osoitintyyppejä, elleivät ne ole ”todella läpinäkymättömiä evästetyyppejä – ne vain sekoita asioita
struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck;
Mitä tarkoitan läpinäkymättömällä evästetyypillä ? Tarkoitan jotain, jota käytetään moduulin (tai kirjaston tai mikä tahansa), joka on välitettävä asiakaskoodille, mutta kyseistä asiakaskoodia ei voi <äyttää suoraan. Se vain välittää sen takaisin kirjastoon.
Esimerkiksi tietokantakirjasto saattaa paljastaa käyttöliittymän, kuten
/* Lots of buffering, IPC and metadata magic held in here. No, you don"t get to look inside. */ struct DBContextT; /* In fact, you only ever get a pointer, so let"s give it a nice name */ typedef struct DBContexT *DBContext; DBContext db_allocate_context(/*maybe some optional flags?*/); void db_release_context(DBContext); int db_connect(DBContext, const char *connect); int db_disconnect(DBContext); int db_execute(DBContext, const char *sql);
Nyt konteksti on läpinäkymätön asiakaskoodille, koska et voi katsoa sisälle. Välität sen vain takaisin kirjastoon. Jotain
FILE
on myös läpinäkymätön, ja kokonaislukutiedoston kuvaus on myös eväste , mutta ei ole läpinäkymätön.
Huomautus suunnittelusta
Käytin yllä olevaa ilmausta matala kytkentä ja korkea koheesio ilman selityksiä, ja minusta tuntuu siitä hieman huono. Voit etsiä sitä ja todennäköisesti löytää hyviä tuloksia, mutta yritän käsitellä sitä lyhyesti (voisin taas kirjoittaa esseen, mutta yritän olla tekemättä).
Yllä oleva luonnos DB-kirjastosta näyttää matala kytkentä , koska se paljastaa pienen käyttöliittymän ulkomaailmaan. Piilottamalla toteutuksen yksityiskohdat (osittain läpinäkymättömillä evästetemppuilla) se estää asiakaskoodin riippuvan näistä yksityiskohdista. p> Kuvittele läpinäkymättömän evästeen sijasta julistamme kontekstirakenteen siten, että sen sisältö on näkyvissä, ja se sisältää socket-tiedostokuvaajan TCP-yhteydelle tietokantaan. Jos myöhemmin muutamme toteutusta tukemaan jaetun muistisegmentin käyttöä, kun Tietokanta on käynnissä samalla koneella, asiakas on koottava uudelleen eikä vain linkitettävä uudelleen. Vielä pahempaa on, että asiakas olisi voinut aloittaa käyttää tiedostokuvaajaa, esimerkiksi kutsua setsockopt
muuttaa oletuspuskurin kokoa, ja nyt se tarvitsee myös koodimuutoksen. Kaikki nämä yksityiskohdat Ne tulisi piilottaa moduulimme sisään, jos se on käytännöllistä, ja tämä antaa vähäisen kytkennän moduulien välillä.
Esimerkki osoittaa myös korkean koheesion , koska kaikki moduulin menetelmät koskevat samaa tehtävää (DB-pääsy). Tämä tarkoittaa, että vain koodilla, joka tarvitsee tietää toteutuksen yksityiskohdista (eli evästeen sisällöstä), on tosiasiallisesti pääsy niihin, mikä yksinkertaistaa virheenkorjausta.
Voit myös nähdä, että yhden huolenaihe helpotti etuliitteen valitsemista näiden toimintojen ryhmittelemiseksi.
Tämän esimerkin sanominen on helppoa (varsinkin kun se ei ole ”ei edes valmis”, mutta ei auta sinua välittömästi. Temppu on katsella, kun kirjoitat ja laajennat koodia, toiminnoille, jotka tekevät samankaltaisia asioita tai toimivat samantyyppisille (jotka voivat olla ehdokkaita omalle moduulilleen), ja myös toimintoihin, jotka tekevät paljon erillisiä asioita, joita ei ole ” Ei todellakaan ole yhteydessä toisiinsa, ja se voi olla ehdokas jakautumiselle.
Kommentit
- Voitteko auttaa minua ymmärtämään, miksi unkaria vältetään? siitä. 🙂
- @JNL: Kommentti on liian lyhyt selittääkseen oikein. Ehdotan, että lähetät sen uudeksi kysymykseksi.
-
with low coupling and high cohesion
. Mitä tämä tarkoittaa? Ja selittäkää läpinäkymättömistä evästetyypeistä. Minulla ei ole aavistustakaan, mitä se tarkoittaa. - Yritin puhua molemmista lyhyesti ja epäonnistuin suoraan sanottuna. Toivottavasti sen pitäisi saada sinut alkoi.
- Vastaan muutaman päivän kuluttua. Anteeksi. Luin sinun kuvauksesi
low coupling and high cohesion
. Joten se tarkoittaa periaatteessa kapseloida asioita, kun voin ja se olisi tehtävä tavalla, joka toiminnoille, jotka todella tarvitsevat, pitäisi olla pääsy. Jotkut asiat menivät päähäni, mutta silti luulen, että sain mielipiteesi.
Vastaa
Mielestäni 90 % nimeämisongelmasta ratkaistaan, jos pidät mielessä kolme asiaa: a) tekevät muuttujien ja funktioiden nimistä yhtä kuvaavia kuin mahdollista, b) oltava johdonmukaisia koko koodissasi (ts. jos funktiolle annetaan nimi addNumbers, toisen funktion tulisi olla nimeltään multiplyNumbers eikä numerotMul) ja c) yritä tehdä nimistä lyhyitä, koska ne on kirjoitettava.
Tästä huolimatta, jos haluat tarkastella muita tämän aiheen näkökohtia, Wikipedia-sivulla Nimeämiskäytännöt sisältää hyvän luettelon asioista, joita sinun pitäisi pitää mielessä. Siinä on myös sekvenssi C: ssä ja C ++: ssa.
C- ja C ++ -järjestelmissä avainsanat ja kirjastotunnisteet ovat yleensä pieniä kirjaimia. C-standardikirjastossa lyhennetyt nimet ovat yleisimpiä (esim. Isalnum funktion testaamiseksi, onko merkki aakkosnumeerinen), kun taas C ++ -standardikirjasto käyttää usein alaviivaa sanan erottimena (esim. Out_of_range). Makroja edustavat tunnukset kirjoitetaan sopimuksen mukaan vain isoilla kirjaimilla ja alaviivoilla (tämä liittyy monien ohjelmointikielien tapaan käyttää isoja isoja tunnuksia vakioille). Nimet, jotka sisältävät kaksoisviivaa tai alkavat alaviivalla ja isolla kirjaimella, on varattu toteutukseen (kääntäjä, vakiokirjasto), eikä niitä tule käyttää (esim. Varattu__ tai _varattu). [5] [6] Tämä on pinnallisesti samanlainen kuin stropping, mutta semantiikka eroaa: alaviivat ovat osa tunnisteen arvoa, eivätkä ne merkitse merkkejä (kuten stropping): __foo: n arvo on __foo (joka on varattu), ei foo (mutta eri nimiavaruudessa).
Kommentit
- " yritä tehdä nimistä lyhyet, jos mahdollista. " Käytä automaattista täydennystä sisältävää IDE: tä, jolloin toimintojesi nimet voivat olla niin pitkiä ja kuvaavia kuin niiden on oltava, koska tarvitset vain kirjoittaa sitten kerran.
- @Joel kauhistuttavia neuvoja. Kaikki eivät käytä samaa IDE: tä kuin sinä.
- @James Heidän ei tarvitse ' tarvita, he voivat käyttää vain mitä tahansa kunnollista IDE: tä. Silloin sinun ei ' ei tarvitse uhrata selkeyttä tuottavuuden puolesta.
- Termi IDE venytetään hieman ohueksi nyt päivinä. Teknisesti Notepad ++ on IDE, koska voit määrittää sen kääntämään ja suorittamaan projektisi, mutta se ' on ensisijaisesti tekstieditori. Ja se täydentyy automaattisesti.
Vastaus
C: n ainoa vaikea rajoitus on, että nimitiloja ei ole. Siksi sinun on löydettävä tapa erottaa tiedostojärjestelmän kirjastosi rename()
-funktio rename()
media -kirjastosi toiminto. Tavallinen ratkaisu on etuliite, kuten: filesystem_rename()
ja media_rename()
.
Muu yleinen neuvo on: stay johdonmukainen projektin tai ryhmän sisällä. Luettavuus paranee.
Kommentit
- +1: Tämä pätee erityisesti kirjastossa vietyihin symboleihin. " Olen pahoillani, mutta tiedostojärjestelmäkirjasto ei sovi kyseisen mediakirjaston kanssa, koska molemmilla on viety funktion uudelleennimeys.
Vastaa
JOS Etsitkö maailmanlaajuisesti HYVÄKSYTTY FORMAATTI
MISRA / JSF / AUTOSAR kattaa lähes 100% kaikista alan standardeista C / C ++ -koodien nimeämisessä ja järjestämisessä. Ongelmana on, että he eivät saa ilmaiseksi käsiinsä, ts. Jokainen opas maksaa jonkin verran rahaa. Tiedän, että MISRA 2008 C / C ++ -koodausstandardikirja todennäköisesti maksaa noin 50 USD.
Voit ajatella näitä Harvardin kirjallisuusluettelon ja lisäyslukemisen viitteinä kirjoittaessasi päiväkirjaa. Olen käyttänyt MISRAa ja se on hyvä tapa nimetä toiminnot ja muuttujat ja järjestää ne asianmukaista käyttöä varten.
JOS ETTÄTÄTÄTÄÄN JOKAA AJANA
Pythonille ja Java: lle antamasi viitteet ovat luultavasti kunnossa. Olen nähnyt ihmisten hyväksyvän javadoc-tyylin kommentoimaan, nimeämään ja järjestämään koodia. Itse asiassa minun oli viimeisessä projektissani kirjoitettava C ++ -koodi Java-tyyppisiin funktioihin / muuttujien nimiin. Kaksi syytä tähän:
1) Sen noudattaminen oli ilmeisesti helpompaa.
2) Tuotantokoodivaatimukset eivät koskeneet turvallisuuden kannalta kriittisten ohjelmistojärjestelmien standardeja.
3) Vanha koodi oli (jotenkin) siinä muodossa.
4) Doxygen salli Javadoc-sytlen kommentoimisen. Tuolloin käytimme doxygenia tuotannon kavereiden dokumentaation luomiseen.
Monet ohjelmoijat ovat tämän vastustajia, mutta henkilökohtaisesti olen sitä mieltä, että javadoc-tyylisen funktion / muuttujanimien käyttöönotossa C: ssä ei ole mitään vikaa. / C ++. KYLLÄ tietysti, virtauksen ohjauksen, langan turvallisuuden jne. Järjestämiskäytännöt on käsiteltävä riippumatta. En kuitenkaan ole hakija täällä. En myöskään tiedä kuinka tiukat tuotantokoodin muodolliset vaatimukset ovat. Siirtämättä sitä aiheen ulkopuoliselle alueelle, suosittelen tarkistamaan vaatimukset, selvittämään kuinka riippuvainen olet tietystä nimeämiskäytännöstä ja etsimään mainitun ratkaisun kanssa minun ja muiden vastauksissa
Toivottavasti tämä auttoi !?
Kommentit
- Oikeastaan pyysin tätä henkilökohtaisista C-koodeista . Mutta ' muistan ehdotuksesi.
- @AseemBansal Henkilökohtainen tai ammattilainen, niitä on hyvä oppia ja myös hyvä laittaa ansioluettelosi 🙂 … Sinusta.
Vastaa
Muutama tärkeä asia, joka on otettava huomioon nimeämisen yhteydessä;
-
Katso actionObject- tai ObjectAction-tyyppiä. (Object not for C. Mutta yleensä kun siirryt muille Object Oriented Language -kielille) Tämän pitäisi auttaa
-
Lepo olisi YHDENMUKAISTA, lyhyt ja varmasti kuvailevaa.
- Ole myös jokaisen määritellyn muuttujan ja funktion ainoa tarkoitus, Esim .: Jos se tallentaa arvon väliaikaisesti, nimeä se int-arvoksi nTempVal
- Muuttujien tulee olla substantiiveja ja Methods-verbien.
Kommentit
- Unkarilainen merkintätapa (muuttujan etuliite kirjainta merkitsevällä tyypillä) ei johda kivun loppuun. Onneksi se on onneksi mennyt muodista.
- @StevenBurnap Oli vain utelias, miksi unkarilaista muotoa vältetään? Uskon, että ' on se, mitä he opettivat meille koulussa, ja olen nähnyt tällaisen koodin myös joissakin työpaikoissa. Kumpaakin suosittelisit, ellei unkaria. Kiitos
- Paras nimeämiskäytäntö on vain yksi johdonmukaisesti käytetty, selkeät, kuvaavat nimet, jotka pidetään ihanteellisesti suhteellisen lyhyinä ilman liiallisia lyhenteitä ja välttämättömiä etuliitteitä. Unkarilaisella merkinnällä on vähän todellista hyötyä, se tekee koodista vaikeampaa lukea ja vaikeuttaa tyyppien vaihtamista.
- Tässä on kuvaus alkuperäisestä tarkoituksesta ja kauhistuksesta, josta unkarilaisesta merkinnästä on tullut: joelonsoftware.com/articles/Wrong.html
- @Residuum Se oli hyvä linkki. Auttoi paljon. Arvostan sitä.
Vastaa
Suurin osa vastauksista on hyviä, mutta haluan sanoa joitain asioita nimeämisestä kirjastojen ja mukana olevien tiedostojen käytännöt, samanlainen kuin nimitilojen käyttö muilla kielillä, kuten C ++ tai Java:
Jos rakennat kirjaston, etsi vietävä symboleillesi yhteinen etuliite, ts. globaalit toiminnot, typedefit ja muuttujat. Tämä estää ristiriitoja muiden kirjastojen kanssa ja tunnistaa toiminnot omistamastasi kirjastosta. Tämä on vähän sovellusten unkarilaisia merkintöjä.
Ehkä mene vielä pidemmälle ja ryhmittele viedyt symbolit: libcurl käyttää curl_ *: ta yleisiin symboleihin, curl_easy_ *, curl_multi_ * ja curl_share_ * eri rajapintoihin.Joten sen lisäksi, että curl_ * on käytetty kaikkiin toimintoihin, he ovat lisänneet toisen tason ”nimitiloja” eri rajapinnoille: curl_easy_ * -funktion kutsuminen curl_multi_ * -kahvassa näyttää nyt väärältä, katso funktioiden nimet osoitteesta http://curl.haxx.se/libcurl/c/
Säilyttäessä vietyjen symbolien säännöt, sinun tulee käyttää niitä staattisten toimintojen kohdalla kohdassa #include
muokatut tiedostot: Yritä löytää yhteinen etuliite näille toiminnoille. Ehkä sinulla on staattisia merkkijonoapuohjelman toimintoja tiedostossa nimeltä ”my_string”? Etuliitä kaikki nämä toiminnot my_string_ * -merkillä.
Kommentit
- Viemillä symboleilla tarkoitat globaaleja muuttujia, funktioita, typefefeja jne., Jos olen oikeassa. Voitteko selittää vähän vietyjen symbolien ryhmittelystä? Luulin, että selitit sen jo edellisessä kappaleessa. Mitä lisäsit 3. kappaleeseen?
order.c
, voit nimetä funktiotorder_add()
,order_del()
ja vastaavat. Saattaa olla vanhoja järjestelmiä, jotka kertovat, että nimen on oltava yksilöllinen kahdeksan ensimmäisen merkin sisällä. Kun vaihdat vahingossa c ++: een myöhemmin, ' rakastat kirjoittaaorder::add()
jaorder::del()
sitten.