Java a statické metody

Re:Java a statické metody
« Odpověď #15 kdy: 20. 10. 2015, 13:22:47 »
Podle mne statické importy obvykle kód znepřehledňují, protože nevím, odkud se ta metoda bere…

Jako bys to normalne vedel. Pozdni vazba skoro vsude, takze stejne musis spolehat na nejakou dalsi znalost. Nemluve o tom, ze zrovna u statickych importu je podpora v IDE prikladna. Samozrejme muzes psat
Kód: [Vybrat]
Math.max(a,b) misto
Kód: [Vybrat]
max(a,b), nebo
Kód: [Vybrat]
VectorUtils.sum(a,b) misto
Kód: [Vybrat]
sum(a,b) ale ja osobne v tom vyhodu nevidim. (jinak pro jistotu: urcite se najde i situace, kdy je lepsi se kvuli stylu static importu vyhnout, ale osobne bych ho bral jako defaultni reseni)


Re:Java a statické metody
« Odpověď #16 kdy: 20. 10. 2015, 13:52:20 »

Normálně to právě vím. A připadá mi mnohem lepší zápis Math.max(a, b), než když vidím napsáno jenom max(a, b) a musím pátrat po tom, zda je to Math.max(a, b) nebo VectorUtils.max(a, b) nebo ještě něco jiného.

Re:Java a statické metody
« Odpověď #17 kdy: 20. 10. 2015, 14:11:02 »

Normálně to právě vím. A připadá mi mnohem lepší zápis Math.max(a, b), než když vidím napsáno jenom max(a, b) a musím pátrat po tom, zda je to Math.max(a, b) nebo VectorUtils.max(a, b) nebo ještě něco jiného.

Kdyz ctes logiku kodu, tak ti to muze byt pro prvni cteni jedno a pak staci kouknout na typy nebo prinejhorsim najet mysitkem...

n

Re:Java a statické metody
« Odpověď #18 kdy: 20. 10. 2015, 15:46:31 »
Diky za pouceni o statickych importech. Neznal jsem to. Ale to me problemy neresi.
Typickou třídou, která obsahuje jen statické metody, je například Math. Nic neukládá, nic neloguje. Pokud v té své třídě potřebuješ logovat, bylo by vhodné to logování vložit jako parametr konstruktoru ....

Logovat potrebuju obcas. Transformace nejsou uplne trivialni(i kdyz raketova veda to neni; kvuli ladeni se mi ale hodi debug logy; u nekterych skladanych si loguju  casy), ale opravdu si zadne stavy nedrzi a ani to nema smysl.

n

Re:Java a statické metody
« Odpověď #19 kdy: 20. 10. 2015, 16:03:38 »

s logermi je to fpohode, trieda ma static final logger, instanciu ziska z factory ktora rozhodne ako ten logger nakonfiguruje podla prostredia (loggery ale nemaju staticke metody...)

To rozlišení jsem psal o něco dříve – pokud ten kód nezávisí na ničem dalším a určitě nikdy v budoucnosti záviset nebude, tedy pokud jsou to typicky jednořádkové nebo třířádkové metody, použil bych util třídu se statickými metodami. Jakmile tam je nějaká logika, dá se očekávat, že tam budou vznikat nějaké závislosti nebo vytýkání kódu, použil bych singleton – ušetřím si tím problémy v budoucnosti.

Asi jsem to nepobral uplne. Ok, chapu singleton. Ne ze by se to nedalo, ale precejen "filozoficky" nevidim duvod ani pro tu jednu instanci. :-) Triradkove metody to nejsou, ale treba neco na urovni Collections.sort()
Hodim sem priklad:
Kód: [Vybrat]
public final class Utils {
  private static final Logger LOG = Logger.getLog(...);

  public static String trans1(...) { ... LOG ... }
  public static String trans2(...) { ... }

  private Utils() {}
}

Tak a ted co s tim LOGem v pripade ze chci resit testy. Pochopil jsem to spravne, ze bych mel
spravne v testu zdedit Logger a tomu predefinovat getLog aby vracel treba neco, co nic nedela?


Re:Java a statické metody
« Odpověď #20 kdy: 20. 10. 2015, 16:29:31 »
Ten příklad je k ničemu, protože o tom, zda je lepší singleton nebo statické metody, se budete rozhodovat podle kódu těch metod, ne podle jejich hlavičky.

Důvod pro tu jednu instanci je tehdy, pokud ten kód těch metod bude trochu složitější, a budete z nich volat jiné metody a jiné služby.  V případě statických metod pak musíte mít závislost na těch jiných službách natvrdo v kódu, a nezměníte ji ani třeba pro účely testů. V případě singletonu předáte ty závislosti jako parametr při vytváření té instance, takže pokud ji potřebujete vyměnit, jenom zavoláte konstruktor s jiným parametrem, ale na té implementaci singletonu nic neměníte.

Collections.sort() je zrovna případ, který by bylo lepší řešit pomocí singletonu – a jako statické metody je to řešeno jednak kvůli stáří té třídy (přeci jen v té době poněkud chyběly Java best practices), jednak aby se to snadno použilo i ve velmi primitivních aplikacích. Jinak by bylo rozumné té třídě umožnit předat třeba implementaci řadicího algoritmu, výchozí comparátor, výchozí locale pro řazení apod.

F.

Re:Java a statické metody
« Odpověď #21 kdy: 20. 10. 2015, 16:57:50 »
Se vsichni na tu implementaci Collections.sort() v jave 8 podivejte, urcite vas prekvapi :-).

perceptron

Re:Java a statické metody
« Odpověď #22 kdy: 20. 10. 2015, 20:01:56 »
Citace
Tak a ted co s tim LOGem v pripade ze chci resit testy. Pochopil jsem to spravne, ze bych mel
spravne v testu zdedit Logger a tomu predefinovat getLog aby vracel treba neco, co nic nedela?

aky je problem s loggermi?

moj workflow: slf4j + logback (log4j funguje rovnako). jeden bezny XML v src/main/resources, unit-testovy v src/test/resources. logback v unit testoch vyzdvihne ten unitestovy, logback v deployment vyzdvihne ten v src/main


Franta <xkucf03/>

Re:Java a statické metody
« Odpověď #23 kdy: 20. 10. 2015, 20:30:43 »
Udelam privatni konstruktor a udelam tridu finalni.
Mne se jedna o to, jestli se to v Jave takto opravdu resi(myslim ta trida statickych metod).

Ano, je to návrhový vzor knihovní třída (utility) a používá se i ve standardní knihovně Javy.

Je řada případů, kdy je to legitimní a správné řešení.

Na druhé straně důvody proti:
  • potřebujeme držet stav (zřejmé), nebo pokud v budoucnu budeme chtít držet stav (a nemusí to být stav z obchodního hlediska, ale i technická záležitost jako zkompilovaný regulární výraz nebo XSLT šablona, načtený konfigurák, inicializovaný „marshaller“ nebo něco podobného)
  • budeme chtít změnit chování – implementovat rozhraní nebo potomka třídy a metodu tam přepsat – to u statické metody nelze
  • statické metody příliš svazují kód – odkaz na statickou metodu je v něm zadrátovaný a nelze ho předat zvenku jako parametr. To v Javě 8 už neplatí, ale je potřeba statické metody tímto způsobem skutečně používat – pak vlastně nepoužíváme statickou metodu, ale nějaké rozhraní a jestli nám zvenku přijde jako parametr odkaz na statickou metodu nebo nějaká jiná implementace, je nám jedno
  • špatně se testují („mockují“) – nejhorší je, pokud je v nich zadrátovaná nějaká komunikace s okolím (načítání něčeho ze souborů, výpis na standardní výstup, čtení uživatelského vstupu atd.). To se netýká jen testů, ale i případů, kdy chceme program použít nějakým novým způsobem nebo ho přebudovat.

Kit

Re:Java a statické metody
« Odpověď #24 kdy: 20. 10. 2015, 21:37:52 »
Typickou třídou, která obsahuje jen statické metody, je například Math. Nic neukládá, nic neloguje. Pokud v té své třídě potřebuješ logovat, bylo by vhodné to logování vložit jako parametr konstruktoru ....

Logovat potrebuju obcas. Transformace nejsou uplne trivialni(i kdyz raketova veda to neni; kvuli ladeni se mi ale hodi debug logy; u nekterych skladanych si loguju  casy), ale opravdu si zadne stavy nedrzi a ani to nema smysl.

Drží si stav. Ten logger má přece jako vložený objekt - je to jeho atribut.

Re:Java a statické metody
« Odpověď #25 kdy: 20. 10. 2015, 22:39:12 »
rekl bych to takhle: jestli to ma nejaky vnitrni stav -> singleton, nema-li vnitrni stav -> static

Jestlize pri kazdym volani metody se stejnymi parametry musi byt stejny vysledek, tak to zadnej vnitrni stav nema a udelej to static (cimz de facto uzivateli knihovni tridy tuto informaci sdelis), pokud pri volani se stejnymi parametry se vysledek muze lisit (coz je skoro vzdy zpusobeno vnitrnim stavem), tak je to singleton. Jako singletony obvykle byvaji ruzni spravci (spravce spojeni s DB, od kteryho chces ziskat spojeni, atd..., spravci jinych (globalnich) prostredku)

Kit

Re:Java a statické metody
« Odpověď #26 kdy: 20. 10. 2015, 23:28:31 »
Jako singletony obvykle byvaji ruzni spravci (spravce spojeni s DB, od kteryho chces ziskat spojeni, atd..., spravci jinych (globalnich) prostredku)

To je pěkná hloupost. Co když potřebuji pracovat s několika databázemi? Co když potřebuji logovat do dvou nezávislých systémů? Co to mají být ty "globální" prostředky? No fuj!

Singleton je v takových případech totálně k ničemu. Jeho jediným smysluplným použitím je NullObject.

Radek Miček

Re:Java a statické metody
« Odpověď #27 kdy: 20. 10. 2015, 23:54:00 »
Jako singletony obvykle byvaji ruzni spravci (spravce spojeni s DB, od kteryho chces ziskat spojeni, atd..., spravci jinych (globalnich) prostredku)

To je pěkná hloupost. Co když potřebuji pracovat s několika databázemi? Co když potřebuji logovat do dvou nezávislých systémů? Co to mají být ty "globální" prostředky? No fuj!

Například funkce nebo třídy jsou v podstatě globální hodnoty a problém s tím nutně nemusí být. Záleží, zda máte stav a kam ho ukládáte. Stav můžete například uložit do "thread local" proměnné nebo do nějakého "kontextu", jenž je spojen s výpočtem.

perceptron

Re:Java a statické metody
« Odpověď #28 kdy: 21. 10. 2015, 00:06:36 »
Citace
Co když potřebuji logovat do dvou nezávislých systémů?
java logger je pokojne public static final singleton. konkretny ciel logovania (databaza, subor, whatever) je v kompetencii ineho objektu, teda appendera (plati uz od log4j, cca rok 2001).

prepojenie medzi loggermi a appendermi sa riesi v konfiguraku

Natix

Re:Java a statické metody
« Odpověď #29 kdy: 21. 10. 2015, 00:06:46 »
Loggery bych v testech neřešil, maximálně jak psal výše perceptron, nadefinovat jiný konfigurák pro produkci a pro testy, ale alespoň v opravdu jednotkových testech není logování v principu třeba. A že je to globální stav? To je jedno, logovací výpisy slouží k debugování, ne k řízení logiky programu. A ve chvíli, kdy máš dobré pokrytí testy, tak debugování stejně není moc potřeba.

Na druhou stranu tu mám pěkný protipříklad: unit test, který v PDFku (str/test/resources) hledá hledá německá slova, pro tenhle test zadrátovaná přímo v kódu. Zdrojáky byly samozřejmě v UTF-8, ale i tak pokud jsem test pustil přes Ideu, tak prošel, ale pokud přes Gradle, tak selhal. Vtip byl v chybějící definici options.encoding pro compileTestJava. A povedlo se mi to odhalit až poté, co jsem přidal testovací metodu vypisující na sysout ono německé slovo.