Java a statické metody

n

Java a statické metody
« kdy: 20. 10. 2015, 07:33:16 »
Ahoj,
 mam takovy dotaz. V Jave jsem zacatecnik a chtel bych se zeptat. Jak se spravne v Jave resi nake metody typu "utils". Proste metody, ktere delaji ruzne transformace nad datama. A fakt si nepotrebuji drzet zadne stavy ani dalsi informace.

Predpokladam ze staticke metody? Co trida, ktera obsahuje jen takovou kupu metod? Trida nelze udelat staticka(teda top-level trida),
muzu samozrejme zabranit vytvoreni instance(coz je logicke - ty instance fakt nemaji smysl).

Jde mi o nejake best practises v Jave. Ted mne nezajimaji jine jazyky. Ty samozrejme maji jine moznosti, jak se s timto vyporadat.
« Poslední změna: 20. 10. 2015, 08:06:10 od Petr Krčmář »


Krtek + Krtek

Re:Java a staticke metody
« Odpověď #1 kdy: 20. 10. 2015, 08:00:18 »
Trida sice nejde udelat staticka, ale zato muzes pouzit "privatni" konstruktor tj.

public class MojeTrida {

  private MojeTrida() {
  }

}

no a takhle uz si nikdo zadnou instanci tyhle tridy nevyrobi.

n

Re:Java a statické metody
« Odpověď #2 kdy: 20. 10. 2015, 08:13:47 »
Jj, to tam pisu, ze tomu muzu zabranit.
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).

Re:Java a statické metody
« Odpověď #3 kdy: 20. 10. 2015, 08:36:02 »
Ano, opravdu se to tak řeší.

Problém budeš mít v testech, volání takových metod se blbě mockuje. Pokud nemají sideefecty a jenom (čistě ve smyslu FP) transformují data, dá se s tím asi  žít, záleží na dalších okolnostech.

n

Re:Java a statické metody
« Odpověď #4 kdy: 20. 10. 2015, 08:58:53 »
...
Problém budeš mít v testech, volání takových metod se blbě mockuje. Pokud nemají sideefecty a jenom (čistě ve smyslu FP) transformují data, dá se s tím asi  žít, záleží na dalších okolnostech.

No to je nasledujici dotaz, ktery jsem chtel polozit :-) Co se tyka testu:
Metody sice opravdu jen transformuji data, v tom je to celkem "ciste". Ale treba metody neco loguji. Obslehl jsem vytvoreni  objektu loggeru odjinud. A to tak, ze se vytvari jako staticky clen tridy a pak se ve tride jen uz pouziva. Problem je presne v tom co rikas - pri testovani totiz ten log loguje taky a navic se mu neda zmenit konstruktor. (log si nacita konfiguraci ze soubrou) Jak by se toto melo resit? Je spravne reseni predhodit my fejkovany konfigurak(myslim ted v testech)?


perceptron

Re:Java a statické metody
« Odpověď #5 kdy: 20. 10. 2015, 09:38:35 »
utils sa daju riesit aj cez abstraktnu metodu ktora ma len staticke metody, ziadne instancne premenne (mozno okrem loggerov).

ta abstraktnost je trik zo springu ktory brani vyrobeniu instancie


ale tie metody fakt musia byt jednoucelovky co nepotrebuju ziadne instancne premenne ani nevyuzivaju stav sveta, prikladov ma spring plny kopec, vsetky class konciace na Utils: StringUtils, BeanUtils a podobne. ked trieda zacne pouzivat kadejake ine triedy lahko vyleze staticzilla


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...)

Pavel Tišnovský

Re:Java a statické metody
« Odpověď #6 kdy: 20. 10. 2015, 10:03:50 »
Jj, to tam pisu, ze tomu muzu zabranit.
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, dělá se to tak, příkladem je například java.lang.Math:
http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html

Kolemjdoucí

Re:Java a statické metody
« Odpověď #7 kdy: 20. 10. 2015, 10:09:49 »
Jj, to tam pisu, ze tomu muzu zabranit.
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).

Re:Java a statické metody
« Odpověď #8 kdy: 20. 10. 2015, 10:33:54 »
Pokud je to opravdu triviální utilita, která určitě nebude záviset na ničem dalším (např. často testujete, zda řetězec není prázdný, tj. zda není null nebo nemá délku 0 – tak si ty dvě podmínky složíte do jedné metody), dělá se to opravdu tak, že vytvoříte finální třídu se statickými metodami, vytvoříte v ní privátní bezparametrický konstruktor, který vyhazuje výjimku (takže instance nepůjde vytvořit ani děděním nebo reflexí).

Často ale ten kód bude složitější, bude záviset na dalším kódu (nebo to tak může být v budoucnosti). Pak se ta implementace píše jako klasická třída, od které se pak v aplikaci vytvoří jediná instance – singleton. Tahle třída pak může záviset na jiných třídách – a díky tomu, že to jsou instance (které předáváte typicky v konstruktoru, nebo alespoň pomocí setterů), můžete pak implementaci snadno vyměnit, aniž byste musel zasahovat do kódu. Což se hodí třeba v případě testů. Nejspíš brzy dojdete k tomu, že takovýchhle tříd budete mít víc a budou mít různě propletené závislosti – pak se vám hodí nějaký IoC framework, který ty instance bude vytvářet za vás a bude řešit ty závislosti. A obvykle vám pak umožní jenom změnou konfigurace určit, která implementace se má použít.

Jinak to, že máte služby, které dělají jenom nějaké transformace s datama, je naprosto běžná věc. Funguje takhle nejspíš drtivá většina evidenčních aplikací (e-shopy, účetnictví, sklady atd.). Proto také vzniká tolik frameworků, které takovou architekturu programů podporují – ORM, IoC apod. Je to návrat k procedurálnímu programování. V C máte datové struktury a procedury/funkce, které s daty manipulují. Dnes se sice programuje s objekty, ale ve skutečnosti tam často máte zase jen datové entity nebo přepravky, tedy datové struktury, které nemají žádný výkonný kód, a vedle nich služby, které s těmi daty manipulují (ale nemají žádný stav) a které se typicky dělají jako bezstavový singleton.

Re:Java a statické metody
« Odpověď #9 kdy: 20. 10. 2015, 11:12:47 »
Nejsem fanda, ale jeste je potreba statickym metodam dat k dobru
- import static
- v osmicce se celkem citelne pouzivaji reference na ne

A drobne varovani:
Kdysi podobne veci lide resivali i statickymi metodami v interface, cimz se efektivne branilo tvorbe instanci. Do namespace pak misto import static dostavali ty metody pomoci implements. To je dneska povazovano za antipattern.

Kit

Re:Java a statické metody
« Odpověď #10 kdy: 20. 10. 2015, 12:16:34 »
Ahoj,
 mam takovy dotaz. V Jave jsem zacatecnik a chtel bych se zeptat. Jak se spravne v Jave resi nake metody typu "utils". Proste metody, ktere delaji ruzne transformace nad datama. A fakt si nepotrebuji drzet zadne stavy ani dalsi informace.

Predpokladam ze staticke metody? Co trida, ktera obsahuje jen takovou kupu metod? Trida nelze udelat staticka(teda top-level trida),
muzu samozrejme zabranit vytvoreni instance(coz je logicke - ty instance fakt nemaji smysl).

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 - tím pádem už nebudeš mít statickou třídu, ale normální objekt. Metody také nebudou statické, ale klasicky instanční.

Používání statických tříd a metod v Javě fakt nemá valného smyslu - pouze deformují tvůj pohled na řešený problém a bude tě to svádět k procedurálnímu řešení. Udělej to jako normální plnohodnotné objekty a nauč se programovat objektově.

Re:Java a statické metody
« Odpověď #11 kdy: 20. 10. 2015, 12:29:33 »
Ahoj,
 mam takovy dotaz. V Jave jsem zacatecnik a chtel bych se zeptat. Jak se spravne v Jave resi nake metody typu "utils". Proste metody, ktere delaji ruzne transformace nad datama. A fakt si nepotrebuji drzet zadne stavy ani dalsi informace.

Predpokladam ze staticke metody? Co trida, ktera obsahuje jen takovou kupu metod? Trida nelze udelat staticka(teda top-level trida),
muzu samozrejme zabranit vytvoreni instance(coz je logicke - ty instance fakt nemaji smysl).

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 - tím pádem už nebudeš mít statickou třídu, ale normální objekt. Metody také nebudou statické, ale klasicky instanční.

Používání statických tříd a metod v Javě fakt nemá valného smyslu - pouze deformují tvůj pohled na řešený problém a bude tě to svádět k procedurálnímu řešení. Udělej to jako normální plnohodnotné objekty a nauč se programovat objektově.

Jeste jednou - fanda nejsem. Ale OOP neni vsechno a s osmickou jsou staticke metody celkem obstojne nahrazky funkci.

Predat logovani do konstruktoru neni zdaleka jedina moznost, jak to finalne vyresit.

Re:Java a statické metody
« Odpověď #12 kdy: 20. 10. 2015, 12:47:03 »
s osmickou jsou staticke metody celkem obstojne nahrazky funkci
Předpokládám, že vám jde o lambda výrazy – a tam je použití instanční metody úplně stejné, jako použití statické metody. Takže tohle není argument na podporu statických metod.

Re:Java a statické metody
« Odpověď #13 kdy: 20. 10. 2015, 12:53:34 »
s osmickou jsou staticke metody celkem obstojne nahrazky funkci
Předpokládám, že vám jde o lambda výrazy – a tam je použití instanční metody úplně stejné, jako použití statické metody. Takže tohle není argument na podporu statických metod.

Spolu se statickymi importy dostanes o neco citelnejsi kod. Ja bych v tomhle byl pragmatik - pokud je to pure (nebo skoro pure, trebas logovani se da osolichat i jinak) a neni to navazane na konkretni data (kde jasne dava smysl instancni metoda), tak bych se statickych metod nezrikal. Ostatne kdyz se pouzivaji takhle zaroven to signalizuje i ucel.

Takze jako obvykle - resil bych to pripad od pripadu.

Re:Java a statické metody
« Odpověď #14 kdy: 20. 10. 2015, 13:09:25 »
Spolu se statickymi importy dostanes o neco citelnejsi kod. Ja bych v tomhle byl pragmatik - pokud je to pure (nebo skoro pure, trebas logovani se da osolichat i jinak) a neni to navazane na konkretni data (kde jasne dava smysl instancni metoda), tak bych se statickych metod nezrikal. Ostatne kdyz se pouzivaji takhle zaroven to signalizuje i ucel.

Takze jako obvykle - resil bych to pripad od pripadu.
Podle mne statické importy obvykle kód znepřehledňují, protože nevím, odkud se ta metoda bere…

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.