"krájanie kódu", pomenovanie súborov, funkcií, premenných atd. rubrika: Folklór

6 Mlocik97
položil/-a 23.9.2018
 
upravil/-a 23.9.2018

Zdravím,

Mám na Vás 3 otázky ktoré asi sú časté, no zaujímal by ma práve váš názor.

Podľa čoho sa rozhodujete či určitú časť kódu obalíte do samostatnej funkcie? (tu je ešte síce celkom v podstate jasná odpoveď, ale trebárs u Angular controllerov či podobných vecí je to už také, nie úplne jasné, podobne aj u vue componentov)
Podľa čoho sa rozhodujete jak kód rozdelíte medzi súbory?
Podľa čoho určujete názvy súborov, funkcií, premenných atd.?

odkaz
4 vit.herman
odpověděl/-a 23.9.2018

Skvělé otázky.

1) Kód obalím do samostatné funkce přesně v jakémkoli ze dvou případů: buď se nabízí pro daný blok dostatečně deskriptivní název nebo potřebuji v rámci projektu tento blok použít opakovaně (i tam se pokusím nalézt nějaký dobrý název). Totéž platí pro komponenty, třídy, apod.

2) Soubory tvořím obvykle podle konvencí nějakého frameworku nebo firemních konvencí. Nejvíc mi vyhovuje mít na jeden modul jeden soubor. Celkem přirozená věc ve světě JavaScriptu. Ve světě C# moduly ve stejné podobě nejsou, ale zhruba existuje nějaká centrální třída a další typy okolo (enumy, DTO, apod.). Tak soubor pojmenuji podle této centrální třídy a umístím do ní i ty typy okolo. Ve své podstatě mi jde o to, aby souborů nebylo zbytečně moc. Aby když se člověk podívá na projektovou strukturu, aby hned viděl a poznal, z čeho je aplikace složena, ale aby zároveň nebyl dezorientován příliš vysokou granularitou.

3) Jedna z nejtěžších, ale nejdůležitějších věcí vůbec (zvlášť u rozsáhlých projektů). Řídím se tím, že název považuji vždy za abstrakci. To znamená, že již z pojmenování by mělo být co nejlépe jasné, jak se používá a co znamená, aniž by bylo nutné zkoumat detaily. Pokud nedokážu zvolit název, hledám chybu spíše ve špatné dekompozici programu. Spokojen jsem tehdy, pokud již z názvu lze poznat jak se daná abstrakce používá a nemusím zkoumat detaily. Pokud to nedokážu dokonale, pak se to snažím popsat v komentářích. A ani to nedělám, pokud je užití samotné stručnější, než případný komentář.

Napiš pak, jak to děláš Ty, také mne zajímají vaše názory.

Komentáře

  • Mlocik97 : Ja kód balím do samostatných funkcií len když tu funkci opakuju. Názvy mám totálne retardované (v tomto som fakt špatnej, ak bych pracoval v týme, tak by ma zabili). Súbory s tým mám problém, viem že u webových aplikácií je dobré držať čo najmenšie množstvo kvôli počtu requestov, ale viem že nieje zas dobré cpať vše do jedneho súboru, zatím teda udržujem súbory tak aby obsahovali tak do 500 až tisíc riadkov kódu, ktoré so sebou súvisia (i když mám aj súbor len so 6 riadkami kódu). Inak súborov vo svojom projekte mám necelú stovku. Samozrejme záleží aj od komplexnosti webovej aplikácie (resp. akejkoľvek aplikácie). Čo sa týka pomenovaní, kedže na svojom projekte pracujem sám tak to mám pomenované skoro hociako teda dosť špatne, i když myslím že šlo by to aj o hodne horšie. Ale ako premenné a pod. už pomenuvávam aspoň trocha normálnejšie. Komenty používam skôr len ako pomenovanie odsekov kódu. P.S. ak chceš dostať infarkt, odporúčim ti pozrieť sa na tento gist, to je kód ktorý som psal ešte pred rokom. https://gist.github.com/Mlocik97/087d1ce8261fd3498e85f4a645b63d22 23.9.2018
  • vit.herman : No, pěkné :-). Jinak vyčleňovat do funkce jen to, co se duplikuje jsem také ještě donedávna preferoval (trochu jako rebelii proti až moc přehnanému členění). Nakonec jsem trochu ustoupil ve prospěch trochu vyšší úrovně abstrakcí, která se jeví čitelnější. Ale horší, než nečlenit vůbec je členění do nepochopitelných (často účelových) abstrakcí. Jinak v případě webových aplikací jsou produkční bundly nezávislé na členění zdrojových souborů, takže členění pro vývoj a členění pro produkci lze řešit relativně nezávisle. 23.9.2018
  • harrison314 : Ono opakovanie je velmi dobry indikator vynat veci do metody. Tiez pomenovania. A po par rokoch intuicia. Taktiez dobrym indikatorom je cyklomaticka zlozitost a vnaranie if-ov. 25.9.2018
  • harrison314 : @vit.herman: C# triedy patria kazda do jedneho suboru, jazyk to sice nevyzaduje, ale je to dobra praktika. Tam nemas dovod ich davat do jedneho suboru ako v pripade javascriptu, ked spolu suvisia budu v jednom namespace. 25.9.2018
  • vit.herman : @harrison314: Je to samozřejmě hodě standardní konvence a i u nás se jí musím řídit. Přesto podle mého názoru to má nevýhodu v tom, že nerozeznáš na první pohled vždy hlavní třídu od pomocných. Proto si ponechávám soukromý názor, že je lepší mít pomocné typy (a jde vždy o třídy, struktury a enumy) ve stejném souboru. Vede to k přehlednějšímu uspořádání na úrovni souborů. 25.9.2018
  • Kit : @vit.herman: Jaký je rozdíl mezi hlavní a pomocnou třídou? 25.9.2018
  • harrison314 : @vit.herman: Tak, ze pomocne triedy su internal alebo v inom namespace. 25.9.2018
  • vit.herman : @Kit: Pomocné třídy, enumy nebo struktury jsou datové typy vytvořené jen k tomu, aby je mohla použít "hlavní" třída. Např. metoda Image.Rotate(Rotation rotation) přijímá parametr rotation typu enum Rotation, jehož hodnoty mohou být třeba Left,Right. Tento výčet byl navržen pouze k tomu, aby nějaká "hlavní" a "užitečnější" třída měla dobře typovaný parametr a omezila potřebným způsobem vstupní doménu. Pak lze takový typ označit za pomocný. Totéž se může týkat např. DTO tříd nebo agregačních struktur, apod. Jednoduše ale jde o to, že jsou navrženy jen okolo té hlavní třídy. Pokud je takový typ sdílen napříč přes více tříd, je určitě správné mít ho v samostatném souboru. Toto dělení je samozřejmě zhlediska prog. jazyka naprosto umělé a trpí tím nedostatkem, že v méně disciplinovaném týmu se význam toho, co je hlavní a pomocné v průběhu změní, avšak nezmění se struktura souborů. Momentálně ale upřednostňuji benefit spočívající v menším množství souborů. A uznávám, že se to dá řešit také pomocí dobře strukturovaných namespaces. Budu o tom ale přemýšlet. Namespace je pro mne zatím něco ještě trochu většího... 25.9.2018
  • Kit : @vit.herman: V daném případě bych použil metody Image.RotateLeft() a Image.RotateRight(). Pomocná třída je tím pádem fuč. Další možností je udělat takovou třídu jako vnořenou. Jinak viz @harrison314. Namespace je dobré dělat široké a ploché. 25.9.2018
  • vit.herman : @Kit: Zda udělat metodu Rotate(Rotation rotation) s parametrem nebo rovnou RotateLeft() a RotateRight() rozhoduji čistě pragmaticky. Někdy to přichází jako parametr z UI a pak bych potřeboval nějaký switch command. Také tu hodnotu rotation mohu chtít propagovat do privátních metod. To vnoření je dobré řešení. Avšak téměř totožné tomu mému (vše v jednom souboru). A nepoužívám ho jen proto, že vnořené třídy vypadají drobet hůře v zápisech a s případnou kolizí názvu v namespace jsem se ještě nesetkal nebo byl triviálně řešitelný... 25.9.2018
  • Kit : @vit.herman: Ten switch tam bude asi vždycky - buď v metodě, anebo mimo ni. Z UI to obvykle chodí jako dvě události mezi ostatními. Není tedy důvod je spojovat do jednoho enumu a poté zase rozdvojovat v metodě. Ovšem tu aplikaci nevidím, takže mohu jen hádat, jak by to bylo lepší. 25.9.2018
  • vit.herman : @Kit: Úplně jednoduše si představ, že máš v UI dva radio buttony. Teď ani nehodnoťme užitečnost takového UI, prostě je to vstup. Přijde Ti hodnota 90 nebo 270 v jedné proměnné formuláře. No a k tomu je ideální ten enum (uvažuji teď C#, pro úplnost), jeho hodnoty Left a Right definuji jako 270, resp. 90. V tu chvíli žádný switch skutečně nebude nikde potřeba, protože postačí přetypování. A celé jsem to postavím právě takto protože to je a) korektní b) nejjednodušší 25.9.2018
  • Kit : @vit.herman: V daném případě bych do metody poslal přímo to číslo 90 nebo 270. Však ta metoda si s tím poradí, ne? Opět bez pomocné třídy... 25.9.2018
  • harrison314 : @vit.herman: Ved na to netreba namespace, podla prikadu maju dane triedy samoopisne mena. 25.9.2018
  • vit.herman : @Kit: Ale já chci ten vstup omezit na ta dvě čísla. Je to součástí kontraktu metody. Nechci, aby to někdo mohl zavolat třeba s hodnotou 36. Šlo by o porušení domény. A v silně typovaném jazyce je pokus řešit to přes omezující datový typ základem oproti runtime kontrole. Runtime kontrolu použiji tehdy, pokud mi na to typový systém nestačí. 26.9.2018
  • Kit : @vit.herman: Z mého pohledu je ten kontrakt chybně definován. Dejme tomu, že přijde požadavek, aby to umělo i 180. Kolik komponent budeš muset změnit? Já jen jednu. Když mi přijde 36, vyhodím výjimku. Myslím si, že tady jsme narazili na jádro letitého sporu mezi vývojáři. Ošetřovat chybu na vstupu co nejdříve vs. co nejpozději. 26.9.2018
  • vit.herman : @Kit: Chybně zjevně není, byť je třeba jinak, než bys ho dělal Ty. Á ano, může jít přesně o tento spor (je-li v tom spor). V tom případě já ošetřuji co nejdříve a využívám maximálně staticky typovaných jazyků. Proto pro běžné business aplikace preferuji C#, F#, Golang a TypeScript Jinak bych samozřejmě také změnil jen jednu komponentu - ten enum. 26.9.2018
  • Kit : @vit.herman: Proto jsem psal "z mého pohledu". Dávám přednost dynamickému typování a pozdní (příp. velmi pozdní) vazbě. Vzniká tím kratší a přehlednější kód za cenu potřeby náročnějších testů. Pokud bych uvedený příklad dělal například v Javě a měl použít enum dle tvého vzoru, implementoval bych do něj i schopnost otočit vložený obrázek. Takový objekt jen injektuji do objektu z obrázkem, který si ho touto metodou otočí, aniž by tušil, kterým směrem to bude. 26.9.2018
  • Taco : Je omezena doména pro Rotate(Rotation rotation) na čtyři stavy. Není na tom nic špatného, naopak. Je to ukázka správného agilního vývoje - neřešit problém, který nemám, a nekompikovat si život. Vzniká tím kratší a přehlednější kód. 26.9.2018
  • Kit : @Taco: A co bys řekl na tohle? Rotation rotate = new Rotation(270); picture.action(rotate); Takovým objektem "rotate" můžeš rotovat co chceš. Na zmíněné čtyři stavy ho omezíš už v jeho konstruktoru, který může zpracovávat kromě čísel třeba i stringy "left" nebo "right". 26.9.2018
  • Taco : @Kit: Budu se citovat: "neřešit problém, který nemám, a nekompikovat si život." Enum Rotation je dostatečnou abstrakcí. Má čtyři stavy, které potřebuju. Pokud se něco změní, tak to zohledním. Do té doby je ten Enum přesně to co potřebuju. Nic víc nic méně. 26.9.2018
  • vit.herman : @Taco: Díky za dobré shrnutí toho, o co skutečně jde. @Kit: Ale to pak můžeme ukončit debatu. Nemá cenu se přít o to, zda je lepší dynamické typování a pozdní vazba nebo statické typování a časná vazba. Každý přístup je vhodný pro jinou aplikační doménu. A v případě týmového vývoje takových těch "běžných" business aplikací,které děláme u nás a kde je nutné myslet i na to, že i kolega by měl mít možnost provést poměrně efektivně zásah, aniž by se mu to rozbilo, tak je pro mne podstatné použít to nejjednodušší a nejsrozumitelnější vyjádření dané situace v přítomném okamžiku. A to omezení domény pak slouží jako ta nejpřímočařejší dokumentace pro programátora (kód mluví) a jako zábrana, aby se nepřeložilo něco, co jít nemá. Aby to vůbec nešlo zavolat s nepovoleným parametrem. Toť celé. 26.9.2018

Pro zobrazení všech 4 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.