Komentáře
Odpověď
Pokud pokračuji když napíšu více kódu, pak nastane doba, kdy bude pro mě obtížné kód zorganizovat.
Toto je váš problém: dostat organizaci správně, a styl by měl plynout snadněji.
Ne čekejte na uspořádání kódu: udržujte svůj kód uspořádaný tak, jak máte. Ačkoli jazyk to pro vás nedělá, kód by měl být pořád organizován do modulů s nízkou vazbou a vysokou soudržností.
Tyto moduly pak přirozeně poskytují jmenný prostor. Zkraťte název modulu (je-li dlouhý) a předponu názvu funkce u svého modulu, abyste předešli kolizím.
Na úrovni jednotlivých identifikátorů jsou zhruba ve vzestupném pořadí subjektivity:
- vyberte konvenci a držte se jí
- např.
function_like_this(struct TypeLikeThis variable)
je běžný
- např.
-
rozhodně se vyhněte maďarské notaci (omlouvám se, JNL)
-
pokud ji nejste ochotni použít tak, jak bylo původně zamýšleno, což znamená spíše Simonyiho aplikace než ta hrozná verze systému
Proč? Mohl bych o tom napsat esej, ale místo toho navrhuji, abyste si přečetli tento článek Joela Spolského a poté, pokud vás to zajímá, lovili další. Ve spodní části je odkaz na Simonyiho původní papír.
-
-
vyhněte se typedef ukazatele, pokud nejde o skutečně neprůhledné typy souborů cookie – pouze zaměňujte si
struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck;
Co mám na mysli neprůhledným typem souboru cookie ? Mám na mysli něco použitého uvnitř modulu (nebo knihovny nebo cokoli), které musí být předáno klientskému kódu, ale tento klientský kód nelze použít přímo. Prostě ji předá zpět do knihovny.
Například databázová knihovna může vystavit rozhraní jako
/* 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);
Nyní kontext je neprůhledný na kód klienta, protože se nemůžete podívat dovnitř. Stačí jej předat zpět do knihovny. Něco jako
FILE
je také neprůhledné a celočíselný deskriptor souboru je také cookie , ale není neprůhledný.
Poznámka k designu
Použil jsem výše uvedenou frázi nízká spojitost a vysoká soudržnost výše a je mi z toho trochu špatně. Můžete ji vyhledat a pravděpodobně najít dobré výsledky, ale pokusím se jí krátce věnovat (znovu bych mohl napsat esej, ale pokusím se ne).
Načrtnutá knihovna DB ukazuje nízké propojení , protože odhaluje malé rozhraní s vnějším světem. Skrytím podrobností implementace (částečně pomocí triku s neprůhledným souborem cookie) zabrání tomu, aby kód klienta závisel na těchto detailech.
Představte si místo neprůhledného souboru cookie deklarujeme kontextovou strukturu, aby byl viditelný její obsah, a který zahrnuje deskriptor souboru soketu pro připojení TCP k databázi. Pokud následně změníme implementaci tak, aby podporovala použití segmentu sdílené paměti, když DB běží na stejném stroji, je třeba klienta znovu zkompilovat, nikoli pouze znovu propojit. Ještě horší je, že klient mohl začít používat deskriptor souboru, například volat setsockopt
změnit výchozí velikost vyrovnávací paměti a nyní také potřebuje změnu kódu. Všechny tyto podrobnosti ils by měl být skrytý uvnitř našeho modulu, kde je to praktické, a to dává nízkou vazbu mezi moduly.
Příklad také ukazuje vysokou soudržnost , protože všechny metody v modulu se týkají stejné úlohy (přístup DB). To znamená, že k nim má přístup pouze kód, který potřebuje o podrobnostech implementace (tj. Obsah našeho souboru cookie), což zjednodušuje ladění.
Můžete také vidět, že jediný problém usnadnil výběr předpony pro seskupení těchto funkcí dohromady.
Nyní je říkat, že tento příklad je dobrý, snadný (zejména proto, že není „Dokončeno není), ale okamžitě vám nepomůže.“ Trik spočívá v tom, že při psaní a rozšiřování kódu sledujete funkce, které dělají podobné věci nebo fungují na stejných typech (které mohou být kandidáty na jejich vlastní modul), a také funkce, které dělají spoustu samostatných věcí, které nejsou “ Skutečně souvisí a může být kandidátem na rozdělení.
Komentáře
- Pomůžete mi pochopit, proč se maďarštině vyhýbáme? Zajímalo by mě vědět více o tom. 🙂
- @JNL: Komentář je příliš krátký na to, aby se správně vysvětlil. Navrhuji, abyste jej zveřejnili jako novou otázku.
-
with low coupling and high cohesion
. Co to znamená? A vysvětlete prosím neprůhledné typy souborů cookie. Nemám tušení, co to znamená. - Snažil jsem se oba krátce oslovit a upřímně řečeno selhal. Doufám, že by vás to mělo dostat začal ačkoli.
- Odpovídám po několika dnech. Omlouvám se za to. Přečetl jsem si váš popis
low coupling and high cohesion
. Takže to v podstatě znamená zapouzdřit věci, když můžu a mělo by to být provedeno způsobem, který funkce, které skutečně potřebují, by měly mít přístup. Některé věci mi přešly přes hlavu, ale přesto si myslím, že jsem pochopil.
Odpověď
Podle mého názoru 90 % problému s pojmenováním je vyřešeno, pokud pamatujete na tři věci: a) upravte názvy proměnných a funkcí tak popisné jako možné, b) konzistentní v celém kódu (tj. pokud má funkce název addNumbers, druhá funkce by měla mít název multiplyNumbers a ne numbersMul) a c) zkuste názvy zkrátit, pokud je to možné, protože je musíme psát.
To je řečeno, pokud se chcete podívat na další aspekty tohoto tématu, stránka Wikipedie na Konvence pojmenování obsahuje dobrý seznam věcí, které byste měli mějte na paměti. Má také část v C a C ++:
V C a C ++ jsou klíčová slova a standardní identifikátory knihovny většinou malá. Ve standardní knihovně C jsou nejběžnější zkrácené názvy (např. Isalnum pro funkci testující, zda je znak alfanumerický), zatímco standardní knihovna C ++ často používá podtržítko jako oddělovač slov (např. Out_of_range). Identifikátory představující makra jsou podle konvence psány pouze s velkými písmeny a podtržítky (to souvisí s konvencí v mnoha programovacích jazycích používání identifikátorů všech velkých písmen pro konstanty). Názvy obsahující dvojité podtržítko nebo začínající podtržítkem a velkým písmenem jsou vyhrazeny pro implementaci (kompilátor, standardní knihovna) a neměly by být použity (např. Vyhrazeno__ nebo _Rezervováno). [5] [6] To je povrchně podobné jako stropping, ale sémantika se liší: podtržítka jsou součástí hodnoty identifikátoru, spíše než citovat znaky (jako je stropping): hodnota __foo je __foo (což je vyhrazeno), ne foo (ale v jiném oboru jmen).
Komentáře
- " zkuste názvy zkrátit, je-li to možné " Použijte IDE s automatickým dokončováním, názvy vašich funkcí pak mohou být tak dlouhé a popisné, jak je potřeba, jak potřebujete zadat jednou.
- @Joel strašná rada. Ne každý bude používat stejné IDE jako vy.
- @James Nepotřebují ', stačí použít jakékoli slušné IDE. Pak nemusíte ' muset obětovat jasnost kvůli produktivitě.
- Termín IDE je nyní několik dní natažený. Technicky Notepad ++ je IDE, protože jej můžete nakonfigurovat tak, aby zkompiloval a spustil váš projekt, ale ' je to především textový editor. A automaticky se dokončí.
Odpověď
Jediným tvrdým omezením v jazyce C je, že neexistují žádné jmenné prostory. Proto musíte najít způsob, jak funkci rename()
vaší knihovny souborového systému odlišit od rename()
funkce vaší mediální knihovny. Obvyklým řešením je předpona, například: filesystem_rename()
a media_rename()
.
Další obecná rada zní: zůstat konzistentní v rámci projektu nebo týmu. Zlepší se čitelnost.
Komentáře
- +1: To platí zejména pro exportované symboly v knihovně. " Je mi líto, ale knihovna souborového systému s touto knihovnou médií nejde, protože obě mají exportované přejmenování funkce.
Odpověď
POKUD HLEDÁTE GLOBÁLNĚ ACCEPTED FORMAT
MISRA / JSF / AUTOSAR pokrývá téměř 100% jakéhokoli průmyslového standardu pro pojmenování a organizaci kódu C / C ++. Problém je v tom, že se nebudou moci sehnat zdarma, tj. Každý z průvodců stojí nějaké peníze. Vím, že standardní kniha kódování MISRA 2008 C / C ++ pravděpodobně stojí asi 50 USD.
Můžete si je představit jako Harvardské odkazy na bibliografii a čtení při psaní deníku. Použil jsem MISRA a je to dobrý způsob, jak pojmenovat vaše funkce a proměnné a uspořádat je pro správné použití.
POKUD HNEDÁTE NECHČELO DOČASNĚ
Odkazy, které jste poskytli pro Python a Javu, jsou v pořádku. Viděl jsem lidi, kteří přijímají komentování, pojmenování a organizaci kódu ve stylu javadoc. Ve skutečnosti jsem ve svém posledním projektu musel psát kód C ++ v názvech funkcí / proměnných podobných Java. Jsou za tím dva důvody:
1) Bylo to zjevně snazší sledovat.
2) Požadavky na produkční kód se nedotkly základů bezpečnostních standardů softwarového systému.
3) Starší kód byl (nějak) v tomto formátu.
4) Doxygen umožňoval Javadoc sytle komentovat. V tu chvíli jsme pomocí doxygenu generovali dokumentaci pro produkční.
Mnoho programátorů bude proti tomu, ale osobně si myslím, že není nic špatného s přijetím pojmenování funkce / proměnné ve stylu javadoc v C / C ++. ANO KURZU, je třeba řešit postupy organizace vaší kontroly toku, bezpečnosti vláken atd. Bez ohledu na to. Nejsem zde však žadatelem. Také nevím, jak přísné jsou vaše požadavky na formát produkčního kódu. Bez přesměrování do oblasti mimo téma navrhuji, abyste si zkontrolovali své požadavky, zjistili, jak záleží na konkrétní konvenci pojmenování, a šli s uvedeným řešením. v mém a dalších „odpovědi
Doufám, že to pomohlo !?
Komentáře
- Vlastně jsem to žádal o osobní C kódy . Ale ' si váš návrh zapamatuji.
- @AseemBansal Osobní nebo profesionální, je dobré se je naučit a také si dát životopis 🙂 … . Na vás.
Odpověď
Při pojmenovávání je třeba vzít v úvahu několik důležitých věcí;
-
Podívejte se na typ actionObject nebo ObjectAction. (Objekt není pro C. Ale obecně, když přejdete do jiných jazyků orientovaných na objekt) To by mělo pomoci
-
Zbytek by byl BEZ KONZISTENTNÍ, krátký a popisný pro jistotu.
- Také jediný účel každé definované proměnné a funkce, např .: Pokud má dočasně uložit hodnotu, pojmenujte ji jako nTempVal pro int
- Proměnné by měly být podstatné jméno a metody by měly být sloveso.
Komentáře
- Maďarská notace (prefix proměnné písmeny označujícími typ) nevede ke konci bolesti. Naštěstí většinou vyšel z módy.
- @StevenBurnap Bylo jen zvědavé, proč se vyhýbá maďarskému formátu? Věřím, že ' to, co nás učili ve škole, jsem také viděl na některých pracovních místech. Který byste doporučil, ne-li maďarský. Díky
- Nejlepší konvence pojmenování je konzistentně používána pouze s jasnými popisnými názvy, které jsou v ideálním případě udržovány relativně krátké, bez nadměrné zkratky a vyhýbání se nadbytečným předponám. Maďarská notace má malou skutečnou užitečnost, ztěžuje čtení kódu a ztěžuje měnící se typy.
- Zde je popis původního záměru a ohavnosti, kterou se maďarská notace stala: joelonsoftware.com/articles/Wrong.html
- @Residuum To byl dobrý odkaz. Hodně pomohl. Oceníte to.
Odpověď
Většina odpovědí je dobrá, ale chci říci pár věcí o pojmenování konvence pro knihovny a zahrnuté soubory, podobně jako použití jmenných prostorů v jiných jazycích, jako je C ++ nebo Java:
Pokud vytváříte knihovnu, najděte pro své exportované symboly společnou předponu, tj. globální funkce, definice typu a proměnné. Tím zabráníte střetům s jinými knihovnami a zjistíte, že funkce pocházejí z vaší. Toto je malá část maďarských aplikací.
Možná jděte ještě dále a seskupte své exportované symboly: libcurl používá curl_ * pro globální symboly, curl_easy_ *, curl_multi_ * a curl_share_ * pro různá rozhraní.Kromě použití curl_ * pro všechny funkce přidali další úroveň „jmenných prostorů“ pro různá rozhraní: volání funkce curl_easy_ * na curl_multi_ * handle nyní vypadá špatně, viz názvy funkcí na http://curl.haxx.se/libcurl/c/
Při zachování pravidel pro exportované symboly byste měli použít pravidla pro statické funkce v #include
ed soubory: Zkuste najít společnou předponu pro tyto funkce. Možná máte statické obslužné funkce řetězců v souboru s názvem „my_string“? Před všechny tyto funkce přidejte předponu my_string_ *.
Komentáře
- Exportovanými symboly máte na mysli globální proměnné, funkce, definice typu atd., Pokud mám pravdu. Můžete vysvětlit něco o seskupování exportovaných symbolů? Myslel jsem, že jste to vysvětlili již v předchozím odstavci. Co jste přidali ve 3. odstavci?
order.c
, můžete pojmenovat funkceorder_add()
,order_del()
atd. Mohou existovat staré systémy, které vám řeknou, že název musí být během prvních 8 znaků jedinečný. Když omylem přejdete na c ++ později, ' rád píšeteorder::add()
aorder::del()
pak.