LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Java (14) - štábní kultura, specifika

Při psaní programů je vhodné dodržovat určité konvence - nejlépe ty, které specifikovali tvůrci jazyka. Na tato pravidla se dnes podíváme. Poté přijde řada i na některá specifika Javy, která se v jiných jazycích buď nevyskytují, nebo mají poněkud odlišný význam.

19.5.2005 09:00 | Lukáš Jelínek | Články autora | přečteno 31211×

Konvence pro psaní kódu

V následujících odstavcích společně projdeme jednotlivými pravidly pro psaní kódu. Nebude to vyčerpávající popis, zájemci o detaily nechť si přečtou přímo příslušné dokumenty. Nejedná se samozřejmě o žádné dogma, ale vřele každému doporučuji, aby se těchto pravidel držel. Je velmi nepříjemné, když někdo čte sám po sobě kód napsaný před několika měsíci, a již není schopen rozluštit, co bylo jak míněno. O problémech při předávání kódu mezi programátory ani nemluvím.

Jmenné konvence

Při pojmenovávání čehokoliv ve svých programech se v maximální možné míře snažíme používat angličtinu. U mezinárodních projektů je to naprosto nezbytné, ale i v ostatních případech se to hodí. Je to přehlednější, názornější a logičtější, už vzhledem k obrovskému množství tříd ve standardních knihovnách (čím větší míra konzistence jmen s těmito knihovnami, tím lépe).

Každý název by měl co nejlépe vystihovat smysl toho, co se jím pojmenovává. Je dobré se vyvarovat nejednoznačností, podobností znaků a dalších vizuálně problematických věcí, které by činily kód méně přehledný. Vyhýbáme se také zbytečně dlouhým názvům.

Pro jednotlivé kategorie identifikátorů používáme různá pravidla:

  • Balíky (package) pojmenováváme podle svého určení a dodržujeme hierarchii vycházející z URL. Používáme opačný zápis oproti klasickým URL, za doménou pokračujeme dalšími upřesňujícími názvy (např. podle projektů a jejich částí). Názvy píšeme malými písmeny, např. net.somejavaproject.mail, org.somejavaproject.db.cache
  • Rozhraní (interface) mají název podle schopnosti dělat nějakou činnost (Runnable, Throwable, Serializable) nebo podle svého určení (ResultSet, Collection, Iterator). Používají se malá písmena, velké jen na začátku celého názvu a případně dalších slov v názvu.
  • Třídy (class) se pojmenovávají podle účelu a vlastností třídy. Škála může být velmi široká. Je dobré se vyhýbat již existujícím názvů, pokud lze třídu pojmenovat jinak a není to na úkor srozumitelnosti. Název by měl být tvořen jen podstatnými a přídavnými jmény. Příklady: Object, String, ClassCastException
  • Konstanty pojmenováváme podle svého logického významu, nikoli podle hodnoty, kterou nesou; tedy např. FOREGROUND_COLOR a ne LIGHT_GREEN_COLOR. Mohou existovat výjimky, ale to se bude týkat spíš knihoven než normálního programu. Používají se velká písmena, případně číslice, slova se oddělují podtržítky.
  • Proměnné se opět pojmenovávají podle významu. Název se tvoří z malých písmen, velká se používají na začátku slov uvnitř názvu. Pozor na podtržítko (je to platný znak, ale silně nedoporučený), velmi snadno se přehlédne. Pro pomocné proměnné (indexy, řídicí proměnné apod.) si lze vystačit s jednopísmennými názvy. Příklady: fileName, result, i, x
  • Názvy metod by měly vycházet ze sloves (provádějí činnosti), používají se malá písmena, na začátku slov uvnitř názvu pak velká (run(), createObject(), eraseAllItems()). Pro přístupové metody (tedy ty, jejichž prostřednictvím pouze přistupujeme k datům uloženým v objektu) se používá speciální konvence. Metody, které získávají data z objektu, začínají buď get... (např. getColor(), getLastIndex()), nebo, pokud je návratová hodnota typu boolean, podle situace buď is... nebo has... (isReady(), hasFocus()). Metody zapisující hodnotu do objektu mají potom prefix set... (tedy setColor(), setFocus(), setEnabled()).

Soubory a struktura adresářů

Java počítá s tím, že každá třída (kromě vnořených) nebo rozhraní má svůj vlastní soubor. Soubor nese název třídy (rozhraní) a u zdrojového souboru se přidává přípona .java. Zkompilovaný soubor má potom příponu .class, pokud jsou ve zdrojovém souboru deklarovány nějaké vnořené třídy, pro každou kompilátor vytvoří zvláštní soubor (k názvu zapouzdřující třídy přidá název vnořené třídy oddělený znakem dolaru; podobně i u vícenásobného vnoření). Anonymní třídy mají také své soubory .class, ale místo názvu vnořené třídy kompilátor použije pořadové číslo. Příklad: Máme třídu MyClass a v ní vnořenou třídu MyNestedClass. Budeme mít tedy zdrojový soubor MyClass.java a z něj kompilátor vytvoří soubory MyClass.class a MyClass$MyNestedClass.class.

Adresářová struktura musí odpovídat členění balíku. Máme-li tedy balík net.mycompany.jproj.db, potom musíme mít adresářovou cestu net/mycompany/jproj/db.

Obecná pravidla pro psaní kódu

Vlastní kód píšeme vždy tak, aby byl co nejpřehlednější a nejsrozumitelnější. Vyvarujeme se zejména příliš dlouhých řádků (přes 80 znaků), ale i zbytečného "rozcourávání" kódu. Odsazujeme obvykle po čtyřech mezerách (i když někdy mohou být vhodnější dvě). Řádky zalamujeme vždy tak, aby věci, které k sobě logicky patří, byly na stejném řádku. Vhodné místo pro zalomení je za čárkou a před operátorem. Výrazy se snažíme zalamovat na co nejvyšší úrovni vnoření. Text na novém řádku by měl začínat tam, kde na předchozím řádku začíná daná úroveň, případně, pokud by to nevypadalo dobře, odsadíme text osm mezer od začátku řádku. Příklady nebudu uvádět, odkazuji na velmi srozumitelné příklady v popisu konvencí.

Pro zvýšení čitelnosti vkládáme do kódu prázdné řádky. Jsou vhodné zejména mezi metodami, před blokovým nebo řádkovým komentářem, mezi deklaracemi lokálních proměnných a výkonnými příkazy, a dále všude tam, kde to přispěje k čitelnosti kódu. Někde (např. mezi jednotlivými sekcemi v kódu) vkládáme dva prázdné řádky.

Podobné to je s mezerami v řádcích. Také ty dáváme do míst, kde zvýší přehlednost (přesná místa uvádí specifikace). Unární, inkrementační a dekrementační operátory však nikdy od svých operandů neoddělujeme.

Další podobná pravidla (např. co psát na jeden řádek a co rozdělit, v jakém pořadí deklarovat členské proměnné apod.) uvádí specifikace. Jejich porušení není velkou chybou, ale přece jen může poněkud zhoršit čitelnost kódu.

Pravidla pro programování

Zatímco předchozí pravidla byla ryze formální záležitostí bez vlivu na funkci programu, nyní přejdeme k závažnějším pravidlům - a ta už se budou týkat samotného programování. Jejich nedodržováním si můžeme snadno přivodit zbytečné nepříjemnosti.

  • Nejmenší možná viditelnost. Každá členská proměnná třídy a každá metoda by měla mít jen takový stupeň viditelnosti, který nezbytně potřebuje. Je hrubou chybou (která je bohužel často k vidění) deklarovat všechny metody (nebo dokonce proměnné) jako public, tedy s viditelností odkudkoliv. Dobrou cestou je deklarovat proměnné jako private (příp. default nebo protected) a poskytovat přístupové metody. Také metody určené jen k vnitřnímu použití ochráníme proti přístupu zvnějšku. Veřejné proměnné mají svůj smysl pouze u velmi jednoduchých tříd (nahrazujících struktury známé z C/C++), které používáme pouze k předávání dat (viz např. java.awt.Point).
  • Nepoužívat vícenásobná současná přiřazení. Někteří programátoři "odkojení" jazykem C rádi používají složité výrazy, kde se současně přiřazuje, vyhodnocuje atd. celá řada věcí. Sice to zabere málo místa v kódu, ale je to nečitelné a zcela proti duchu Javy. Každé přiřazení si zaslouží samostatný řádek.
  • Raději více závorek než méně. Protože úrovní priority operátorů je celá řada, je lepší se jistit závorkami navíc, než spoléhat na to, že se to vyhodnotí ve správném pořadí. Platí to zejména u ternárního operátoru, kde to navíc významně přispěje k přehlednosti.
  • Pozor na zbytečné testy boolovské hodnoty. Má-li metoda vracet pravdivostní hodnotu, a tato je již k dispozici, není samozřejmě nutné ji znovu testovat. Tento občas viděný zlozvyk pochází z C++ a je způsoben schizmatem v reprezentaci pravdivostní hodnoty (bool vs. "BOOL definovaný jako int") - i když to nebylo nutné, často se dělala explicitní porovnání. Proto se to občas objeví i v Javě. Ovšem pozor - v Javě není hodnota boolean přetypovatelná na žádný jiný primitivní typ (ani obráceně), takže pokud máme číselnou (třeba int) hodnotu, kompilátor by její přímé vracení jako boolean ani nepovolil.
  • Při deklaraci proměnnou vždy hned inicializovat. To je dobrý zvyk, protože máme zajištěno, že proměnná bude mít vždy nějakou předem určenou hodnotu, i když se na ni zapomene. Každý programátor určitě potvrdí, že neinicializované proměnné jsou v každém jazyce hodně nepříjemnou komplikací.

Specifika Javy

Každý jazyk má své specifické věci, které buď jinde nenajdeme, anebo mají (více či méně) jiný význam. Proto je dobré tyto věci znát (aspoň trochu) dřív, než začneme tvořit nějaké větší programy.

Modifikátory

V deklaracích rozhraní, tříd, metod a proměnných můžeme uvádět tzv. modifikátory, které určitým způsobem mění vlastnosti toho, co deklarujeme. Některé modifikátory jsou přítomny i v jiných jazycích (např. v C++), jiné nikoli.

  • final - uvádí se u třídy, metody či proměnné a znamená, že daná entita je "konečná" a nelze ji měnit. U třídy to znamená, že od ní nelze odvodit potomka, metodu takto označenou nemůžeme v potomkovi předefinovat, proměnná nesmí po inicializaci změnit hodnotu (jinými slovy - je to konstanta). Pokud je proměnná referenčního typu, odkazovaný objekt lze měnit, ale "hodnotu odkazu" nikoliv.
  • abstract - uvádí se u třídy nebo u metody, a znamená abstraktní třídu či metodu. Abstraktní třída je třída neúplně definovaná (má některé metody deklarovány, ale ne definovány), nelze vytvářet její instance - je určena k odvozování potomků. Pokud metodu deklarujeme jako abstraktní, nepíšeme už její tělo a musíme jako abstraktní deklarovat i třídu.
  • static - uvádí se u metod a proměnných. Takto deklarovaná metoda je metodou třídy (tedy nikoli instance), z dané třídy může přistupovat jen ke staticky deklarovaným proměnným a volat jen staticky definované metody.
  • transient - uvádí se u proměnných. Znamená, že při serializaci (tedy transformaci objektu do datové podoby určené k uložení nebo přenosu) se bude tato proměnná ignorovat. Zabrání zbytečnému uložení nepotřebných dat, někdy je dokonce podmínkou úspěšné serializace (implicitně se serializují veškeré objekty, na něž daný objekt odkazuje - a ty nemusí vždy serializaci podporovat).
  • volatile - uvádí se u proměnných. Označuje proměnnou, která může změnit svoji hodnotu nějakým "nestandardním" způsobem a přístup k ní tedy nelze optimalizovat (běžně si každé vlákno vytváří pracovní kopii sdílených dat, modifikace se musí synchronizovat) - každý přístup bude znamenat přístup přímo k této proměnné.
  • synchronized - používá se u metod, případně bloků (synchronizované bloky). Cílem je zajistit synchronizaci přístupu vláken k danému objektu. Při zavolání metody (nebo vstupu do synchronizovaného bloku) se objekt zamkne a vlákno, které metodu zavolá následně, bude pozastaveno do doby, než první vlákno metodu opustí.
  • strictfp - používá se u rozhraní a tříd. Vynutí použití striktní matematiky plovoucí řádové čárky (pro zajištění plné kompatibility, stejných výsledků na všech platformách).

Finalizace

Protože se v Javě nepoužívají destruktory, nemáme možnost při rušení objektu provést činnosti, které uvolňují prostředky použité objektem. Existuje ale jedna cesta, jak to částečně nahradit - finalizace.

Třída může definovat speciální metodu, tzv. finalizátor (metoda finalize()). Tato metoda se volá po tom, co se na objekt přestalo odkazovat, ale ještě předtím, než se uvolní (garbage collectorem) paměť obsazená danou instancí objektu.

Používání finalizace se ovšem nedoporučuje. Není totiž záruka, kdy, a zda vůbec, se finalizátor zavolá (záleží to na implementaci JVM). Proto na finalizaci nelze spoléhat a není tedy prakticky žádný důvod ji používat. Lepším postupem je vytvořit si pro daný účel nějakou normální metodu a tu ve správný okamžik explicitně zavolat.

Vnořené třídy

Třídy lze prakticky libovolně vnořovat. Běžně není důvod vytvářet vnořené třídy, výjimkou jsou případy, kdy potřebujeme vytvořit třídu, kterou budeme používat pouze (nebo téměř pouze) v kontextu třídy, do níž vnořujeme:

public class OuterClass {
    protected class InnerClass {
        ...
    }
    
    ...
}

Podobně jako třídy lze vnořovat i rozhraní. Vnořený objekt pak identifikujeme pomocí tečkové notace, pro výše uvedený příklad to bude OuterClass.InnerClass; jako příklad vnořeného rozhraní mohu uvést třeba java.util.Map.Entry.

Pro každou vnořenou třídu kompilátor samostatný soubor - viz výše (odstavec o adresářové struktuře).

Anonymní třídy

Speciálním případem vnořených tříd jsou třídy anonymní. Nemají vlastní název a definují se až v místě, kde je použijeme. Jako základ můžeme použít kteroukoli třídu nebo rozhraní (nesmí být final; všechny abstraktní metody musíme implementovat).

Anonymní třídy jsou nesmírně silný nástroj, ale současně také nebezpečný. Snadnost použití svádí k nadužívání, což vede ke zbytečnému opakování stejného kódu, zhoršení přehlednosti a v neposlední řadě také zbytečné paměťové i časové složitosti. Správným postupem je používat je jen tam, kde se daný kód použije opravdu jen jednou - při opakování je lepší vytvořit standardní třídu.

Thread t = new Thread() {
    public void run() {
       System.out.println("startuji...");
       ...
    }
};

t.start();

Uvedený příklad ukazuje vytvoření anonymní třídy jako potomka třídy Thread. Předefinováváme zde jedinou metodu run(). Pro každou anonymní třídu vytvoří kompilátor samostatný soubor.

Vstup a výstup

Tímto bych tedy tuto kapitolu, věnovanou javově specifickým věcem, uzavřel. Příště opět přejdeme k praktičtějším věcem, konkrétně k základům vstupně/výstupních operací. V Javě k tomu máme k dispozici silný aparát, proto je práce samotná úplnou hračkou.

Verze pro tisk

pridej.cz

 

DISKUZE

Nejsou žádné diskuzní příspěvky u dané položky.



Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

14.11.2017 16:56 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze