Pekny clanek, co se tyce obsahu asi nejpraktictejsi z cele serie.
V kazdem pripade musim mit pripominky k tomu, jakym stylem je kod napsan.
V Jave je po desetileti zazita CamelCaseSyntaxe, hybrid Camel_Case_A_Snake_Case dela kod strasne necitelny. Venuji se tomu uz i puvodni javovske Coding Conventions.
Co ale urcite nepochopim, je, jak muze zkuseny programator napsat:
if (position.equals(Parameters.TEACHER_POSITION) == true) { ... }
misto prosteho if (position.equals(Parameters.TEACHER_POSITION))
. A negovana varianta je snad jeste horsi: if (started == false) { ... }
, kdyz if (!started) { ... }
je mnohem kratsi a srozumitelnejsi. Clovek to muze cist rovnou jako if not started ....
Díky za slova uznání k obsahu článku.
No a co se týče formy -- každý má nějakého kostlivce ve skříni ;-)
Ale vážně.
1) CamelCaseSyntaxe
V naprosté většině svých programů (a i ve výuce) používám důsledně CamelCase syntaxi.
Ale v tomto projektu jsou z důvodů namapování názvů tříd na položky menu aplikace použity velmi dlouhé názvy tříd. A ty jsou často podobné pro studenta i učitele. Po několika pokusech se mi zdál jako nejpřehlednější zápis použití podtržítka jako oddělovače.
2) Nadbytečné porovnávání na true a false
Máte naprostou pravdu, že se to tímto způsobem moc často nepíše a nějaký statický analyzátor (tuším, že PMD) tento způsob identifikuje jako prohřešek. Ovšem je to můj zvyk a připadá mi to přehlednější. Zejména právě v případě testu na false, kdy při svém věku ;-) už úvodní vykřičník snadno přehlédnu.
Ale pokud k celému článku máte jen tyto výhrady, pak mám docela dobrý pocit ;-)
Pavel Herout
@Pavel Herout
2) Nadbytečné porovnávání na true a false
Tak vykřičník se dá přehlédnout i ve spěchu protože třeba deploy nebo nad ránem či ospalém dnu ... zbytečně se pak člověk musí soustředit na to aby nepřehlédl žádnou špécii a kulišárnu která je cool a produkuje nějakou další podmínku nebo ještě nějak doupravuje chování
Např. starý známu Wordpress měl v koding standardu dokonce
if ( ! $var) {}
nebo jsem viděl i radu
if (false == $var) {}
Aby nedošlo omylem při překlepu '=' - to se pak teprve blbě hledá ve 2am ;-)
Nejsem si jistý jak přesně u Javy, ale takto striktně porovnávat je velmi výhodné, protože je to dobře viditelné, vše je jasné, různé jazyky se různě chovají k tomu co považují za TRUE/FALSE, výstup z funkce se může s verzí změnit, může se s verzí změnit interní funkce jazyka - o tom by se dalo sebatovat dlouho, s použitím takto jasně definovaného porovnání není potřeba předpokládat, zjišťovat a debatovat + dnes se neprogramuje jen v jednom jazyku a tohle mi připadá zrovna jako užitečný zvyk ...
18. 10. 2019, 13:21 editováno autorem komentáře
zbytečně se pak člověk musí soustředit na to aby nepřehlédl žádnou špécii a kulišárnu která je cool a produkuje nějakou další podmínku nebo ještě nějak doupravuje chování
Myslite, ze to je zrovna ten pripad? Pokud je podminka slozita a hrozi prehlednuti, je lepsi ulozit pravdivostni hodnotu do pomocne promenne nebo promennych. Nazev te promenne pomuze vysvetlit, o co jde.
Misto:
if (!((foo() > 100) && (qux().bar > 2000))) { ... }
Je mnohem lepsi psat:
boolean isFooBar = (foo() > 100) && (qux().bar > 2000);
if (!isFooBar) { ... }
Aby nedošlo omylem při překlepu '='
Toto v Jave neni realny problem.
takto striktně porovnávat je velmi výhodné, protože je to dobře viditelné, vše je jasné
Zbytecny boilerplate kod je to, co programy v Jave opravdu potrebuji.
Že Vám do toho coby nejavista lezu:
1. Pro tenhle případ krásně funguje De Morgan, tudíž nebudu používat takhle (bez urážky) dementní podmínku a napíšu
if ((foo <= 100) || (qux().bar <= 2000)) {...}
a jsem s čitelností úplně někde jinde.
2. Pokud je podmínka příšerně složitá, použiju funkci (v Javě metodu) a tam si tu logiku nasekám jak se mi to hodí, třeba:
bool isFooBar(foo, bar, baz) { if (foo < 100) return false; else if (bar < 2000) return false else if (baz >= 123) return false; else return true; }
Mám to za jedny peníze (pokud zanedbám jedno volání funkce, což prakticky vždycky můžu) a namísto toho, abych tu volající funkci/metodu prodlužoval dalšími proměnnými, naopak si ji zkrátím a to vyhodnocování si dám zvlášť, kde se to dá hezky okomentovat a všechno je jasné, rozumně krátké a hezké dle libosti.
20. 10. 2019, 19:57 editováno autorem komentáře
"Camel_Case_A_Snake_Case dela kod strasne necitelny".
To je Váš dojem. Když navrhovali Ada, nebo Eiffel, ta došli k opačnému názoru.
Eiffel navíc pro třídy používá formu POINT_TYPE, Ada Point_Type. Je to o zvyku. Třeba mě se
obecně čte snake case líp. V .NET C# sem v testech v knihách viděl právě i tuhle uvedenou formu co je v článku.
No a v F# se dá psát `Test s mezerama` .)
Když navrhovali Ada, nebo Eiffel, ta došli k opačnému názoru.
Tady je rec o Jave, ktera ma jednoduche a zavedene konvence, kterych se drtiva vetsina programatoru drzi. Cokoliv, co jde proti zazitym konvencim, je proto jako pest na oko.
V .NET C# sem v testech v knihách viděl právě i tuhle uvedenou formu co je v článku.
V .NET plati jina pravidla. Treba, ze verejne metody zacinaji velkym pismenem. Kdyz .NETista, zacne tento zvyk uplatnovat v Jave, je v lepsim pripade za jelito, protoze kazdy (v Jave) vi, ze velkym pismenem zacinaji nazvy trid. Cist pak takovy kod je o nekolik radu slozitejsi a pomalejsi.
Díky za článek. JUnit 5 jsme nasadili a je super, že i na starém projektu není třeba nic přepisovat. Těším se hlavně až budou dotažené scenářové testy https://github.com/junit-team/junit5/issues/48. Dále bych ještě vyzdvyhnul, možnost vytvářet testy přes factory metody. Dále se mi líbí, že v posledních verzích přibyl artefakt junit-jupiter
, který spojuje ty potřebné artefakty do jedné dependency. Je hrozně fajn, že s každou verzí JUnit 5 je psaní testů lepší a lepší.