Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: n 20. 10. 2015, 07:33:16

Název: Java a statické metody
Přispěvatel: n 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.
Název: Re:Java a staticke metody
Přispěvatel: Krtek + Krtek 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ázev: Re:Java a statické metody
Přispěvatel: n 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).
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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ázev: Re:Java a statické metody
Přispěvatel: n 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)?
Název: Re:Java a statické metody
Přispěvatel: perceptron 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...)
Název: Re:Java a statické metody
Přispěvatel: Pavel Tišnovský 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
Název: Re:Java a statické metody
Přispěvatel: Kolemjdoucí 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).
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 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.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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.
Název: Re:Java a statické metody
Přispěvatel: Kit 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ě.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 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.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 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.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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)
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 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.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 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ázev: Re:Java a statické metody
Přispěvatel: n 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ázev: Re:Java a statické metody
Přispěvatel: n 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?
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 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.
Název: Re:Java a statické metody
Přispěvatel: F. 20. 10. 2015, 16:57:50
Se vsichni na tu implementaci Collections.sort() v jave 8 podivejte, urcite vas prekvapi :-).
Název: Re:Java a statické metody
Přispěvatel: perceptron 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

Název: Re:Java a statické metody
Přispěvatel: Franta <xkucf03/> 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:
Název: Re:Java a statické metody
Přispěvatel: Kit 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.
Název: Re:Java a statické metody
Přispěvatel: Ziktofel 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)
Název: Re:Java a statické metody
Přispěvatel: Kit 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.
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 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.
Název: Re:Java a statické metody
Přispěvatel: perceptron 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
Název: Re:Java a statické metody
Přispěvatel: Natix 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.
Název: Re:Java a statické metody
Přispěvatel: Natix 21. 10. 2015, 00:28:06
A singletony nebrat nebo se z toho zblázníš! Ale je to marný, nedají si říct a pak musí používat harakiri typu PowerMock, aby vůbec mohli něco testovat, aniž by musela běžet celá aplikace včetně UIčka a databáze.  :)

Ale vážně, singleton dává smysl v určitých případech. Jedním z nich je bezestavový singleton. Ten není problém testovat, nicméně sám o sobě nedává žádné výhody proti statickým metodám. Vtip je v tom, že může implementovat nějaké rozhraní, tzn. že tu instanci můžeme pak použít v nějakých obecných metodách. Příkladem budiž singleton pro prázdný list v java.util.Collections:

Kód: [Vybrat]
public static final List EMPTY_LIST = new EmptyList<>();
private static class EmptyList<E> extends AbstractList<E>

nebo identita v Guavě:

Kód: [Vybrat]
// enum singleton pattern
private enum IdentityFunction implements Function<Object, Object> {
    INSTANCE;

Obecně jsou tohohle patternu JDK nebo právě Guava plné.

Druhý typ singletonu je tzv. efektivní singleton, což je úplně normální třída, která nijak nebrání vícenásobnému instancování, akorát se prostě v celé aplikaci vyrobí jenom jedna instance a ta se všude předává jako argument kontruktorům nebo metodám. Tím pádem zase není problém ji unit testovat. Samozřejmě je opruz si ji takhle přehazovat jako horkej brambor, ale to řeší dependency injection kontejnery jako Spring nebo Guice.
Název: Re:Java a statické metody
Přispěvatel: F. 21. 10. 2015, 10:38:42
A singletony nebrat nebo se z toho zblázníš! Ale je to marný, nedají si říct a pak musí používat harakiri typu PowerMock, aby vůbec mohli něco testovat, aniž by musela běžet celá aplikace včetně UIčka a databáze.  :)

...

Druhý typ singletonu je tzv. efektivní singleton, což je úplně normální třída, která nijak nebrání vícenásobnému instancování, akorát se prostě v celé aplikaci vyrobí jenom jedna instance

Pokud ten "pravy" singleton nema zadne dalsi zavislosti, nebo aspon implementuje nejake rozhrani tak to testovatelne je celkem bez problemu (uzivatele toho singletonu samozrejme nesmi pouzivat MySingleton.getInstance(), ale klasicky dependenci injection).

Ale jinak je tohle asi nejbliz tomu, co je videt v praxi (enterprise vyvoj na zakazku), a uplne souhlasim.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 21. 10. 2015, 11:33:28
Pokud ten "pravy" singleton nema zadne dalsi zavislosti, nebo aspon implementuje nejake rozhrani tak to testovatelne je celkem bez problemu (uzivatele toho singletonu samozrejme nesmi pouzivat MySingleton.getInstance(), ale klasicky dependenci injection).
Což je přesně to, co Natix nazývá „efektivní singleton“ a o čem jsem já psal jenom jako o „singletonu“ – prostě uživatel používá nějakou třídu nebo rozhraní, a nestará se o to, odkud vezme implementaci. Za normálního běhu aplikace typicky bude existovat jenom jedna jediná instance, proto se to nazývá singleton – ale nic nebrání mít třeba pro testy jinou implementaci, případně mít za běhu aplikace těch instancí víc a pro dané použití nějakým způsobem vybrat jednu z nich.

Singleton, na který je jeho uživatel pevně navázán (tj. sám získává jeho instanci voláním třeba getInstance()) má z hlediska použití skoro ty samé nevýhody, jako statické metody.
Název: Re:Java a statické metody
Přispěvatel: Kit 21. 10. 2015, 17:31:21
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.

Vracím se k původnímu dotazu, protože většina odpovědí se stáčí ke statickým metodám a singletonům, což rozhodně nepatří k best practices.

Transformaci nad daty uděláš nejlépe tak, že napíšeš normální metody, které přidáš do třídy, ve které se staráš o ta data. Tím se vyhneš všem getterům, setterům, singletonům a dalším zvěrstvům, které nemají s OOP nic společného.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 21. 10. 2015, 19:28:54
Obávám se, že „best practices“ nemůže označovat něco, co skoro nikdo nepoužívá. Ano, váš návrh je čisté OOP, ale to se dnes příliš nepoužívá – dnes se většinou programuje v objektových jazycích a s objekty, ale aplikace fungují procedurálně. Je to mimo jiné proto, že „starat se o data“ lze mnoha různými způsoby, které nepatří na jednu hromadu, a dokonce často ani nemusí být všechny předem známy.
Název: Re:Java a statické metody
Přispěvatel: Kit 21. 10. 2015, 20:35:15
Obávám se, že „best practices“ nemůže označovat něco, co skoro nikdo nepoužívá. Ano, váš návrh je čisté OOP, ale to se dnes příliš nepoužívá – dnes se většinou programuje v objektových jazycích a s objekty, ale aplikace fungují procedurálně. Je to mimo jiné proto, že „starat se o data“ lze mnoha různými způsoby, které nepatří na jednu hromadu, a dokonce často ani nemusí být všechny předem známy.

"Starat se o data" je možné přímo v objektu. Pokud se mu to do objektu nevejde, je to jen známkou toho, že objekt je příliš komplexní a že ho programátor nedokázal správně dekomponovat. Důsledky jsou podobné, jako když někdo zapomene normalizovat databázi: Práce s takovými strukturami je těžkopádná a plná chyb. S rostoucím projektem se z toho stává jedno velké WTF.

Tazatel je začátečníkem. Proč se ho všichni snaží naučit těm nejšpinavějším praktikám, které se dnes používají? Je nutné začít co nejčistějšími objekty. Teprve když to nejde, je zde prostor pro nějakou "denormalizaci", která nemusí vadit, pokud se udrží na uzdě.

Nikdo z nás asi nemůže za to, že mnoho základních knihoven Javy je napsáno prasácky a s neobjektovým rozhraním. To však nesmí být důvodem, proč bychom je měli napodobovat. Je potřeba si na ně napsat vlastní objektové adaptéry a ty používat.

Častým argumentem je, že přísně objektové aplikace jsou pomalé. Není to pravda. Mám opačnou zkušenost: Refaktorováním cizích aplikací do objektů se mi tyto aplikace zkrátily, zpřehlednily a zrychlily. Během přepisu z nich zmizely i chyby, které v původním programu nebyly nijak zřetelné, ale do toho objektového modelu mi "prostě nepasovaly". Přitom běžně stačilo tu postiženou část kódu zcela vypustit, protože byla duplicitní.

Objekty mají data a chování. Přitom si obecně data chrání a vystavují pouze chování. Pokud se někdo pokouší objekty rozdělit na datové a servisní služby, měl by se raději poohlédnout po jiných programovacích jazycích, než je právě Java. Co třeba Cobol? :)
Název: Re:Java a statické metody
Přispěvatel: F. 21. 10. 2015, 21:21:25
Zalezi co za aplikaci pises.

Pokud nejaky gui ve swingu tam tam se OOP imho uspesne pouziva.

Drtiva vetsina aplikaci v jave jsou ale enterprise crudovky, kde jde v podstate jen o presypani dat mezi databazi a uzivatelovym browserem (zjednodusene databaze <-> dao <-> service <-> mvc framework <-> uzivateluv browser)/third party web service. Uz tohle je obrovsky posun od generovani html a javascriptu v ulozenych procedurach, coz se delalo nekdy pred 10 nebo 15 lety.

Zajimalo by me jakym zpusobem bys resil bez getteru konverzi tveho objektu do nejakeho request objektu(dto, ..), ktery je api knihovny/sluzby co pouzivas. To jako udelas neco jako

Kód: [Vybrat]
RequestObject request = entity.convertToRequestObject()
a pridas tak do te tve entity zavislost na RequestObject?? Co kdyz k tomu potrebujes informace od jinud? Treba nejaky opravneni?
Název: Re:Java a statické metody
Přispěvatel: Kit 21. 10. 2015, 23:25:51
Zajimalo by me jakym zpusobem bys resil bez getteru konverzi tveho objektu do nejakeho request objektu(dto, ..), ktery je api knihovny/sluzby co pouzivas. To jako udelas neco jako

Kód: [Vybrat]
RequestObject request = entity.convertToRequestObject()
a pridas tak do te tve entity zavislost na RequestObject?? Co kdyz k tomu potrebujes informace od jinud? Treba nejaky opravneni?

Zapomněl jsi specifikovat, co se má na co konvertovat. Nevím, co má být v objektu třídy RequestObject, v knihovnách Javy jsem tu třídu nenašel. Také nevím, jaké třídy je objekt entity a co má dělat metoda convertToRequestObject(), která jí evidentně nepatří. Co po něm budeš požadovat? Popsané rozhraní prostě rozdělím na více menších.

Kód: [Vybrat]
Dto dto = request.presentate(entity)
Objekt entity implementuje rozhraní Presentable, metoda request.presentate() si ji v entity zavolá jako entity.show() s výsledkem v rozhraní Showable a zkonvertuje ji do objektu rozhraní Dto. Možná to vypadá trochu chaoticky, ale vzhledem k tomu, že mám chaotické zadání, to zas tak moc nevadí.

Hlavním pravidlem OOP je: Tell, do'nt ask. Je porušeno už v zadání, tak si příště vymysli jiný příklad. Nepotřebuješ request, ale response.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 06:53:11
Tazatel je začátečníkem. Proč se ho všichni snaží naučit těm nejšpinavějším praktikám, které se dnes používají? Je nutné začít co nejčistějšími objekty.
To, že OOP je jediný správný přístup a všechno ostatní je špinavé, je čistě váš názor.


Nikdo z nás asi nemůže za to, že mnoho základních knihoven Javy je napsáno prasácky a s neobjektovým rozhraním. To však nesmí být důvodem, proč bychom je měli napodobovat. Je potřeba si na ně napsat vlastní objektové adaptéry a ty používat.

Častým argumentem je, že přísně objektové aplikace jsou pomalé. Není to pravda. Mám opačnou zkušenost: Refaktorováním cizích aplikací do objektů se mi tyto aplikace zkrátily, zpřehlednily a zrychlily. Během přepisu z nich zmizely i chyby, které v původním programu nebyly nijak zřetelné, ale do toho objektového modelu mi "prostě nepasovaly". Přitom běžně stačilo tu postiženou část kódu zcela vypustit, protože byla duplicitní.

Objekty mají data a chování. Přitom si obecně data chrání a vystavují pouze chování.
Tohle asi začátečníkovi moc nepomůže. Popište to na nějakém konkrétním případu, jaké tam budou objekty a co budou dělat. Třeba košík e-shopu s vloženým zbožím, údaje se načítají z relační databáze a vypisují na webovou stránku.

Pokud se někdo pokouší objekty rozdělit na datové a servisní služby, měl by se raději poohlédnout po jiných programovacích jazycích, než je právě Java.
Proč? V Javě se takhle programuje dobře, má pro to spoustu frameworků a je tak napsaných spousta programů.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 22. 10. 2015, 08:26:50
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.

Vracím se k původnímu dotazu, protože většina odpovědí se stáčí ke statickým metodám a singletonům, což rozhodně nepatří k best practices.

Transformaci nad daty uděláš nejlépe tak, že napíšeš normální metody, které přidáš do třídy, ve které se staráš o ta data. Tím se vyhneš všem getterům, setterům, singletonům a dalším zvěrstvům, které nemají s OOP nic společného.

Zníš jako strejda Bob před deseti lety. Dneska už to taky vidí jinak.
Název: Re:Java a statické metody
Přispěvatel: k 22. 10. 2015, 09:17:36
Transformaci nad daty uděláš nejlépe tak, že napíšeš normální metody, které přidáš do třídy, ve které se staráš o ta data. Tím se vyhneš všem getterům, setterům, singletonům a dalším zvěrstvům, které nemají s OOP nic společného.

Tradiční util věci jsou util proto, že nejdou zařadit nikam, třeba DegreesToRadians nebo TransformJsonToXML. TransformJsonToXML nepatří ani do třídy Json ani do třídy XML a nepotřebuje ani svou vlastní třídu když je to pouze jedna procedura. Ve všech normálních jazycích na zeměkouli se to tedy dá jako funkce do namespace, jenom v Javě, kde to z důvodu chyby návrhu jazyka takhle nejde, se to prasí jako statická metoda třídy.

Hlavním pravidlem OOP je: Tell, do'nt ask.

Není a nikdy nebylo. Jedná se možná o návrhový vzor, ale ne o pravidlo OOP.

Kód: [Vybrat]
Dto dto = request.presentate(entity)
Objekt entity implementuje rozhraní Presentable, metoda request.presentate() si ji v entity zavolá jako entity.show() s výsledkem v rozhraní Showable a zkonvertuje ji do objektu rozhraní Dto. Možná to vypadá trochu chaoticky, ale vzhledem k tomu, že mám chaotické zadání, to zas tak moc nevadí.

Bez chaosu je to tohle: Dto dto = namespace::PresentableToDto(entity.show())

Nikdo z nás asi nemůže za to, že mnoho základních knihoven Javy je napsáno prasácky a s neobjektovým rozhraním. To však nesmí být důvodem, proč bychom je měli napodobovat. Je potřeba si na ně napsat vlastní objektové adaptéry a ty používat.

Tak ukaž objektový adaptér na sin, cos, tan spolu se zdůvodněním proč to tak má být :)
Název: Re:Java a statické metody
Přispěvatel: Kit 22. 10. 2015, 09:38:46

Zníš jako strejda Bob před deseti lety. Dneska už to taky vidí jinak.

Některé z jeho pouček také vidím trochu jinak. Neshodneme se například v názoru na tvorbu názvů. Podle mne by téměř vždy mělo stačit jedno slovo, maximálně dvě.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 10:05:46
TransformJsonToXML nepatří ani do třídy Json ani do třídy XML a nepotřebuje ani svou vlastní třídu když je to pouze jedna procedura.
Ta jedna procedura má na vstupu String, InputStream, Reader, URL, File, na výstupu String, OuptutStream, Writer, URL, File, SAX ContentHandler, StAX, W3C DOM Document, dom4j Document, JDOM Document. A dále potřebuje JSON parser a XML serializer. Bude ta jedna procedura mít desítky přetížených variant, nebo to bude spíš rozhraní a třeba JSON parser a XML serializer budou schovány v jedné konkrétní instanci implementující to rozhraní?


Tak ukaž objektový adaptér na sin, cos, tan spolu se zdůvodněním proč to tak má být :)
Opět to samé jako v předchozím případě – můžu mít různé implementace (různé algoritmy, implementace využívající celočíselnou aritmetiku, aritmetiku v plovoucí řádové čárce, využívající GPU). Uživatel asi nechce být závislý na nějaké konkrétní implementaci. Spíš bude záviset na rozhraní, a za běhu dostane v danou chvíli nejlepší dostupnou implementaci.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 10:20:40
Tak ukaž objektový adaptér na sin, cos, tan spolu se zdůvodněním proč to tak má být :)
Opět to samé jako v předchozím případě – můžu mít různé implementace (různé algoritmy, implementace využívající celočíselnou aritmetiku, aritmetiku v plovoucí řádové čárce, využívající GPU). Uživatel asi nechce být závislý na nějaké konkrétní implementaci. Spíš bude záviset na rozhraní, a za běhu dostane v danou chvíli nejlepší dostupnou implementaci.
Já zírám. Opravdu někoho napadne, že by implementace sinu měla jít přehazovat za běhu? Tohle už snad není ani overengineering.

To, že jsou různé algoritmy schované za tou funkcí je přece výhoda. Mně nezajímá postup ale počet platných číslic co dostanu.
Název: Re:Java a statické metody
Přispěvatel: k 22. 10. 2015, 10:38:14
Ta jedna procedura má na vstupu String, InputStream, Reader, URL, File, na výstupu String, OuptutStream, Writer, URL, File, SAX ContentHandler, StAX, W3C DOM Document, dom4j Document, JDOM Document. A dále potřebuje JSON parser a XML serializer. Bude ta jedna procedura mít desítky přetížených variant, nebo to bude spíš rozhraní a třeba JSON parser a XML serializer budou schovány v jedné konkrétní instanci implementující to rozhraní?

Nemá. Jak už se dá tušit z názvu, na vstupu jeden parametr instance Json a na výstupu instance XML a provádí se jeden algoritmus.
Kdo potřebuje větší komfort, tak takový jednoprocedurový postup nepoužije, to je jasné.

Opět to samé jako v předchozím případě – můžu mít různé implementace (různé algoritmy, implementace využívající celočíselnou aritmetiku, aritmetiku v plovoucí řádové čárce, využívající GPU). Uživatel asi nechce být závislý na nějaké konkrétní implementaci. Spíš bude záviset na rozhraní, a za běhu dostane v danou chvíli nejlepší dostupnou implementaci.

Sin, con, tan má v 99 % projektech stejnou implementaci a stejné parametry. Žádné rozhraní není třeba.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 10:42:02
Já zírám. Opravdu někoho napadne, že by implementace sinu měla jít přehazovat za běhu? Tohle už snad není ani overengineering.
Nemusí jít přehazovat za běhu, ale výběr nejlepší možné implementace je logický. Proč bych to mám všude počítat pomalým způsobem jenom proto, že na některých platformách není rychlejší způsob dostupný?

To, že jsou různé algoritmy schované za tou funkcí je přece výhoda. Mně nezajímá postup ale počet platných číslic co dostanu.
Takže jste si to nakonec vysvětlil sám, že by kód neměl záviset na konkrétní implementaci.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 11:05:03
Já zírám. Opravdu někoho napadne, že by implementace sinu měla jít přehazovat za běhu? Tohle už snad není ani overengineering.
Nemusí jít přehazovat za běhu, ale výběr nejlepší možné implementace je logický. Proč bych to mám všude počítat pomalým způsobem jenom proto, že na některých platformách není rychlejší způsob dostupný?
A tohle je argument pro to že pro sinus nestačí úplně jednoduchá funkce? Přece implementace té funkce závisí na platformě.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 11:19:19
A tohle je argument pro to že pro sinus nestačí úplně jednoduchá funkce? Přece implementace té funkce závisí na platformě.
Implementace té funkce závisí na něčem. Takže nemůžu mít ve svém programu závislost na jedné konkrétní implementaci. Kdybych si dal do své aplikace závislost třeba na implementaci, která používá GPU, nebude to fungovat na zařízení, které žádné GPU nemá.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 11:29:20
Implementace té funkce závisí na něčem. Takže nemůžu mít ve svém programu závislost na jedné konkrétní implementaci. Kdybych si dal do své aplikace závislost třeba na implementaci, která používá GPU, nebude to fungovat na zařízení, které žádné GPU nemá.
Já to fakt nechápu. Sinus je matematická funkce R->R. V C(++) a spoustě dalších jazyků je to přetížená funkce float->float, double->double. Na GPU (glsl, hlsl, opencl, cuda) je to všude funkce float->float.

Implementace sinu se volí v době překladu protože na nějaké rozskakování za běhu nemá moc cenu. Spláchnutí pipeline které je s tím spojené se prostě nevyplatí. Sinus je tak low level, že jediná smysluplná volba podle platformy probíhá při překladu.

Fakt mě nenapadá jediný důvod proč ze sinu dělat cokoliv jiného než obyčejnou jednoduchou funkci.
Název: Re:Java a statické metody
Přispěvatel: F. 22. 10. 2015, 11:38:55
Zajimalo by me jakym zpusobem bys resil bez getteru konverzi tveho objektu do nejakeho request objektu(dto, ..), ktery je api knihovny/sluzby co pouzivas. To jako udelas neco jako

Kód: [Vybrat]
RequestObject request = entity.convertToRequestObject()
a pridas tak do te tve entity zavislost na RequestObject?? Co kdyz k tomu potrebujes informace od jinud? Treba nejaky opravneni?

Zapomněl jsi specifikovat, co se má na co konvertovat. Nevím, co má být v objektu třídy RequestObject, v knihovnách Javy jsem tu třídu nenašel. Také nevím, jaké třídy je objekt entity a co má dělat metoda convertToRequestObject(), která jí evidentně nepatří. Co po něm budeš požadovat? Popsané rozhraní prostě rozdělím na více menších.

Kód: [Vybrat]
Dto dto = request.presentate(entity)
Objekt entity implementuje rozhraní Presentable, metoda request.presentate() si ji v entity zavolá jako entity.show() s výsledkem v rozhraní Showable a zkonvertuje ji do objektu rozhraní Dto. Možná to vypadá trochu chaoticky, ale vzhledem k tomu, že mám chaotické zadání, to zas tak moc nevadí.

Hlavním pravidlem OOP je: Tell, do'nt ask. Je porušeno už v zadání, tak si příště vymysli jiný příklad. Nepotřebuješ request, ale response.

Zadani je jednoduche, mas svoji entitu, treba Employee a chces zavolat nejakou 3rd party service, s parametrem treba CreateEmployeeRequest, ten request je vicemene dto, ktere obsahuje vetsinu informaci z te entity (jmeno, email, adresa, oddeleni atd..), takze ve vysledku potrebujes zavolat tohle:

Kód: [Vybrat]
client.createEmployee(createEmployeeRequest);
Takze misto converteru, ktery pomoci getteru vytaha data z entity a nasype je do dto (typicky priklad v java ee / springu):

Kód: [Vybrat]
CreateEmployeeRequest request = entityToCreateRequestConverter.convert(entity);
client.createEmployee(request);

udelas presne co?
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 11:45:24
Implementace sinu se volí v době překladu protože na nějaké rozskakování za běhu nemá moc cenu. Spláchnutí pipeline které je s tím spojené se prostě nevyplatí. Sinus je tak low level, že jediná smysluplná volba podle platformy probíhá při překladu.
Při překladu Java programu bude cílovou platformou JVM, na tom není moc co řešit. Což ale vůbec neznamená, že nemůžete mít různé implementace – pár příkladů už jsem vyjmenoval. Vůbec není potřeba dělat nějaký rozskok za běhu programu – prostě budete mít mezi knihovnami při startu aplikace jednou knihovnu s jednou implementací, a příště tam dáte jinou implementaci.
Název: Re:Java a statické metody
Přispěvatel: perceptron 22. 10. 2015, 11:52:15
Citace
udelas presne co?
skor prejde tava uchom ihly ako da kit priklad architektury. jeho priklady su vyblitky, v jave nerobil, a nevie o com hovori. to sa tyka uz 9 threadov.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 12:10:33
Při překladu Java programu bude cílovou platformou JVM, na tom není moc co řešit. Což ale vůbec neznamená, že nemůžete mít různé implementace – pár příkladů už jsem vyjmenoval. Vůbec není potřeba dělat nějaký rozskok za běhu programu – prostě budete mít mezi knihovnami při startu aplikace jednou knihovnu s jednou implementací, a příště tam dáte jinou implementaci.
Jo, můžu mít různé implementace a pří JIT překladu překladač nějakou vybere. Já tam pořád nevidím ten důvod, proč by měl být sinus cokoliv jiného než jednoduchá funkce. O to tu snad celou dobu jde.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 12:27:21
Já tam pořád nevidím ten důvod, proč by měl být sinus cokoliv jiného než jednoduchá funkce. O to tu snad celou dobu jde.
Ne, nejde tu o to, že by sinus měl být cokoli jiného, než jednoduchá funkce. Jsou to různé jednoduché implementace – jednou je to jednoduchá funkce implementovaná instrukcemi pro celočíselnou aritmetiku, která bude fungovat všude. Podruhé je to jednoduchá funkce implementovaná instrukcemi pro aritmetiku v plovoucí řádové čárce. Potřetí je to jednoduchá funkce implementovaná pomocí instrukcí GPU. A já jako uživatel nechci vybírat, která implementace se použije – protože ani nemusí být vždy všechny dostupné.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 12:33:48
Ne, nejde tu o to, že by sinus měl být cokoli jiného, než jednoduchá funkce. Jsou to různé jednoduché implementace – jednou je to jednoduchá funkce implementovaná instrukcemi pro celočíselnou aritmetiku, která bude fungovat všude. Podruhé je to jednoduchá funkce implementovaná instrukcemi pro aritmetiku v plovoucí řádové čárce. Potřetí je to jednoduchá funkce implementovaná pomocí instrukcí GPU. A já jako uživatel nechci vybírat, která implementace se použije – protože ani nemusí být vždy všechny dostupné.
Tak o čem tu teda diskutujeme, pokud je správně aby byl sinus obyč funkce. Celé tohle vlákno se točí kolem toho že pro některé věci je obyč funkce to nejlepší a sinus tu padl jako příklad.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 12:49:54
Tak o čem tu teda diskutujeme, pokud je správně aby byl sinus obyč funkce. Celé tohle vlákno se točí kolem toho že pro některé věci je obyč funkce to nejlepší a sinus tu padl jako příklad.
Četl jste ten komentář, na který odpovídáte? Máte tři různé implementace jednoduché funkce, někde jsou dostupné všechny, někde třeba jenom jedna z nich. Uživatel té funkce nepotřebuje jednu konkrétní implementaci, on potřebuje nějakou implementaci, a pokud možno takovou, která je v dané chvíli nejlepší.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 13:00:35
Četl jste ten komentář, na který odpovídáte? Máte tři různé implementace jednoduché funkce, někde jsou dostupné všechny, někde třeba jenom jedna z nich. Uživatel té funkce nepotřebuje jednu konkrétní implementaci, on potřebuje nějakou implementaci, a pokud možno takovou, která je v dané chvíli nejlepší.
Ano, četl. Mám jednoduchou funkci sinus a její tři možné implementace z nichž jednu překladač při JIT vybere a použije. Triviální peephole optimalizace. Přesně tak to pokud vím Java dělá, akorát nemá ty jednoduché funkce a musí si vypomáhat statickýma metodama. Proč bych tady měl chtít cokoliv jiného než tu jednoduchou funkci?
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 13:22:47
Mám jednoduchou funkci sinus a její tři možné implementace z nichž jednu překladač při JIT vybere a použije.
Ne, překladač JIT žádnou implementaci nevybere.

Přesně tak to pokud vím Java dělá, akorát nemá ty jednoduché funkce a musí si vypomáhat statickýma metodama.
Ne, JIT žádnou implementaci nevybírá. Kdybyste použil statickou metodu, váš kód na té statické metodě bude záviset a nezměníte to jinak, než změnou zdrojového kódu. Až se za pár let stane běžnou součástí počítačů komponenta, která bude umět sinus počítat tisíckrát rychleji, váš kód bude pořád dál používat starou pomalou metodu počítání na CPU.

Proč bych tady měl chtít cokoliv jiného než tu jednoduchou funkci?
Máte tři různé implementace. Pokud chcete, aby byly vzájemně zastupitelné, musí mít společné rozhraní. Uživatel té funkce používá rozhraní, nemá vazbu přímo na nějakou implementaci. No a pak samozřejmě musíte mít nějaký kód, který dosadí tu konkrétní implementaci.

Třeba budete mít takovýhle kód. Všimněte si, že Calculator neví nic o nějaké konkrétní implementaci. Kdybyste použil statickou metodu, bude Calculator na tuto metodu pevně navázán a bez změny zdrojového kódu tu implementaci nezměníte.
Kód: [Vybrat]
interface TrigonometricFunctions {
  public double sin(double angle);
}

class Calculator {
  private final TrigonometricFunctions trigonometricFunctions;

  public Calculator(TrigonometricFunctions trigonometricFunctions) {
    assert trigonometricFunctions != null;
    this.trigonometricFunctions = trigonometricFunctions;
  }

  public void compute() {
    …
    double sinResult = trigonometricFunctions.sin(0.0d);
    …
  }
}
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 22. 10. 2015, 13:32:43
Kdybyste použil statickou metodu, váš kód na té statické metodě bude záviset a nezměníte to jinak, než změnou zdrojového kódu.

Statická metoda může volat implementaci, jenž je uložena v nějaké statické proměnné, stačí tedy změnit tuto proměnnou.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 13:37:58
Statická metoda může volat implementaci, jenž je uložena v nějaké statické proměnné, stačí tedy změnit tuto proměnnou.
Uživatel je pak ale pořád závislý na implementaci té statické metody. Navíc ta statická proměnná je globální proměnná pro celý classloader, takže když jí jeden uživatel změní, změní implementaci všem.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 13:53:19
Ne, překladač JIT žádnou implementaci nevybere.
Fakt ne?
Citace: Oraclí dokumentace
Unlike some of the numeric methods of class StrictMath, all implementations of the equivalent functions of class Math are not defined to return the bit-for-bit same results. This relaxation permits better-performing implementations where strict reproducibility is not required.

By default many of the Math methods simply call the equivalent method in StrictMath for their implementation. Code generators are encouraged to use platform-specific native libraries or microprocessor instructions, where available, to provide higher-performance implementations of Math methods. Such higher-performance implementations still must conform to the specification for Math.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 14:06:02
Fakt ne?
Fakt ne. Zkuste si napsat svou vlastní implementaci Math.sin() a bez hackování bootclasspath docílit toho, aby ji vaši aplikace použila, když zavoláte java.lang.Math.sin().
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 22. 10. 2015, 14:07:56
Coz plati pro cokoli z java.util, java.lanf, javax atd, atp.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 14:19:02
Coz plati pro cokoli z java.util, java.lanf, javax atd, atp.
Platí to úplně pro cokoli. Pokud budete mít na classpath dvě třídy stejného jména, aplikace to sice přežije<sup>*)</sup>, ale použije je jen jedna třída a z aplikace nedokážete ovlivnit, která.

*) Pokud je to klasická aplikace s jedním classloaderem. Pokud tam bude složitější hierarchie classloaderů, třeba to bude nějaký aplikační server, nemusí to skončit dobře. I když to není problém tříd a classloaderů, ale obvykle používání globálních proměnných, které se používají právě v souvislosti se statickými metodami a pravými singletony.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 14:24:59
Fakt ne?
Fakt ne. Zkuste si napsat svou vlastní implementaci Math.sin() a bez hackování bootclasspath docílit toho, aby ji vaši aplikace použila, když zavoláte java.lang.Math.sin().
Proč bych měl vůbec chtít psát vlastní implementaci? Bavíme se o sinu. Pro ten mají jedinou instrukci už stařičké pentia.

Takže můžu použít jednoduchou funkci, kterou mi překladač může triviální peephole optimalizací a inlinováním nahradit jedinou instrukcí.

Nebo můžu použít virtuální volání, které stojí řádově to samé co ten sinus. Navíc překladači zabráním jakkoliv to volání optimalizovat páč netuší co za objekt tam pak dostane, jaké to má vedlejší efekty a podobně.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 14:31:56
Proč bych měl vůbec chtít psát vlastní implementaci?
Třeba proto, že budete mít procesor, který na to má jedinou instrukci.

Bavíme se o sinu. Pro ten mají jedinou instrukci už stařičké pentia.
Existují i jiné procesory.

Takže můžu použít jednoduchou funkci, kterou mi překladač může triviální peephole optimalizací a inlinováním nahradit jedinou instrukcí.
Bavíme se o Javě. Bytecode nemá instrukci pro sin.

Navíc překladači zabráním jakkoliv to volání optimalizovat páč netuší co za objekt tam pak dostane, jaké to má vedlejší efekty a podobně.
V případě Javy nedělá překladač skoro žádné optimalizace, drtivou většinu jich dělá JIT. A tohle JIT v optimalizaci nijak nebrání, naopak volání virtuálních metod s pouze jednou implementací umí JIT optimalizovat docela dobře.
Název: Re:Java a statické metody
Přispěvatel: JSH 22. 10. 2015, 14:47:29
...
Já už fakt nevím, jak to popsat jinak.

Současný stav : sinus je statická metoda (tzn. jednoduchá funkce). Code generátor ji už teď umí nahradit jedinou instrukcí, pokud ji instrukční sada procesoru má. Nemusím pro to dělat vůbec nic, protože to za mně všechno udělá překladač+runtime.

Proč bych si jako programátor měl komplikovat život nějakou továrnou na abstraktní sinovadla. Co mi to přinese v porovnání se současným stavem? Pokud se objeví nový procesor s novými instrukcemi, tak se pro něj stejně použije nový codegenerátor, který je bude umět. I tam kde se vybírá algoritmus v runtime na základě procesoru se to dělá na podstatně vyší úrovni, protože takhle nízko se to prostě nevyplatí.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 15:16:00

Bavíme se tu best practice. Best practice je udělat to tak, aby se implementace dala vyměňovat, a dělat to v celé knihovně/aplikaci jednotně. To, že zrovna sin() umí na některých platformách JIT optimalizovat, je podružná věc, protože obvykle zrovna tohle nebude kritické místo vašeho programu. Pokud zjistíte, že zrovna ve vašem programu je počítání sinu úzké hrdlo, teprve pak je správný čas na optimalizaci a teprve to je důvod jít proti best practice.

Proč bych si jako programátor měl komplikovat život nějakou továrnou na abstraktní sinovadla.
Protože to není komplikace, ale výrazné zjednodušení. Továrnu samozřejmě nebudete vymýšlet, protože na to máte framework, který vám dělá továrnu pro další desítky objektů – takže není důvod pro jeden jediný objekt to dělat jinak.
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 22. 10. 2015, 15:42:54
Best practice je udělat to tak, aby se implementace dala vyměňovat

Proč myslíte?
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 22. 10. 2015, 15:48:44
http://i.imgur.com/j5b5JCr.jpg
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 16:23:51
Best practice je udělat to tak, aby se implementace dala vyměňovat

Proč myslíte?
V Javě (až do verze 9) například proto, že jinak vzniká propletenec závislostí, který se za chvíli těžko udržuje a spravuje. Když váš kód závisí na rozhraní, nemusí vás zajímat, že implementace bude záviset ještě ne něčem dalším. Pokud závisí na implementaci, ta nejspíš bude záviset na něčem dalším, a tím na tom tranzitivně začne záviset i váš kód.  A také pak kód nejde rozumně testovat.
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 22. 10. 2015, 16:55:51
Best practice je udělat to tak, aby se implementace dala vyměňovat

Proč myslíte?
V Javě (až do verze 9) například proto, že jinak vzniká propletenec závislostí, který se za chvíli těžko udržuje a spravuje. Když váš kód závisí na rozhraní, nemusí vás zajímat, že implementace bude záviset ještě ne něčem dalším. Pokud závisí na implementaci, ta nejspíš bude záviset na něčem dalším, a tím na tom tranzitivně začne záviset i váš kód.  A také pak kód nejde rozumně testovat.

Ano, to může nastat, nicméně jsou i situace, kde to nastat nemusí a kde je velmi nepravděpodobné, že bude třeba implementaci nahradit. V takových situacích je IMO lepší myslet na jednoduchost a přehlednost kódu - tj. klidně zvolit jednu pevnou implementaci.
Název: Re:Java a statické metody
Přispěvatel: Jann 22. 10. 2015, 17:07:47
Tyhle diskuse jsou krásnou ukázkou toho, jak OOP (a la Java apod.) vede k výrobě problémů z něčeho, kde vůbec žádné ve skutečnosti nejsou.
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 22. 10. 2015, 17:11:57
Tyhle diskuse jsou krásnou ukázkou toho, jak OOP (a la Java apod.) vede k výrobě problémů z něčeho, kde vůbec žádné ve skutečnosti nejsou.

Jaké problémy máte na mysli?
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 22. 10. 2015, 17:35:34
Mně to spíś přijde jako braní javy jako záminky pro to si to pěkně overengineerovat. Na duhou stranu by takovéhle nenapadalo programátory, kde jsou first class nebo alespoň top level funkce.

Neřekl bych při tvorbě nějakého echtobecného veřejného API, ale dokud člověk může případně zobecnění dodat za pochodu (což většinou může).
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 22. 10. 2015, 18:03:14
Ano, to může nastat, nicméně jsou i situace, kde to nastat nemusí a kde je velmi nepravděpodobné, že bude třeba implementaci nahradit. V takových situacích je IMO lepší myslet na jednoduchost a přehlednost kódu - tj. klidně zvolit jednu pevnou implementaci.
Podle mne jednoduchost a přehlednost znamená, že pro stejnou věc používám jeden postup – ne že musím pokaždé přemýšlet, zda to v tomhle konkrétním případě ještě má být třída se statickými metodami, nebo už závislost nastavovaná z venku. Navíc už jsem viděl tolik případů, kdy si někdo myslel, že je to velmi nepravděpodobné, a pak se to muselo nějak hackovat… Jinak to „nepravděpodobné, že bude potřeba implementaci nahradit“ taky dost často znamená „nepravděpodobné, že by to někdo chtěl testovat unit testy“. Protože když máte v kódu tvrdou závislost na nějaké implementaci, můžete otestovat jen obojí najednou (váš kód spolu s tou implementací), pak už to není tak docela jednotkový test, no a komplexní testy se zase o poznání hůř píšou a udržují.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 22. 10. 2015, 19:24:05
Pokud chces praci, kde neni potreba myslet, tak programovani neni dobra volba. Ne ze by bylo potreba vzdycky znova vynalezat kolo, ale na druhou stranu - vazne je potreba jeden ze zakladnich prostredku jazyka odmitat jenom protoze jsi linej se zamyslet?

A samozrejme nahrazovani implementace nesouvisi s testovanim te veci unittesty, ale to je pocitam jenom spatna formulace a myslel jsi mockovani pri testech jinych veci?
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 23. 10. 2015, 07:56:23
vazne je potreba jeden ze zakladnich prostredku jazyka odmitat jenom protoze jsi linej se zamyslet?
Já statické metody neodmítám, napsal jsem myslím docela jasně, kdy je podle mne vhodné je použít. Jinak projevem nepřemýšlení je právě to zneužívání statických metod i tam, kde by měla být volná vazba.

A samozrejme nahrazovani implementace nesouvisi s testovanim te veci unittesty, ale to je pocitam jenom spatna formulace a myslel jsi mockovani pri testech jinych veci?
Jenže bez mockování nedokážete otestovat jenom tu jednu komponentu – nanejvýš otestujete komponentu a vše, na čem závisí.
Název: Re:Java a statické metody
Přispěvatel: JSH 23. 10. 2015, 10:50:29
Já statické metody neodmítám, napsal jsem myslím docela jasně, kdy je podle mne vhodné je použít. Jinak projevem nepřemýšlení je právě to zneužívání statických metod i tam, kde by měla být volná vazba.
Pokud navrhujete volnou vazbu i pro goniometrické funkce, tak už opravdu netuším, kde by by bylo vhodné použít statické metody.
Citace
Jenže bez mockování nedokážete otestovat jenom tu jednu komponentu – nanejvýš otestujete komponentu a vše, na čem závisí.
Napřed se otestují závislosti a pak komponenta i se závislostmi? Proč by tohle neměl být unittest? Přece nebudu omezovat unittesty jen na věci, které mají mockovatelné závislosti.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 23. 10. 2015, 11:31:34
Napřed se otestují závislosti a pak komponenta i se závislostmi? Proč by tohle neměl být unittest?
Není to jednotkový test (unit test), protože netestuje jednotku, ale několik jednotek (komponenta a její závislosti). Takové testy také mají smysl, ale jsou komplexnější. A moc pro ně neexistuje nějaká rozšířená podpora, často se k tomu ohýbají nástroje pro jednotkové testy (v Javě JUnit nebo TestNG), ale to nefunguje úplně ideálně. Pak vám třeba při chybě v té závislosti padají i testy závislé komponenty, což je špatně (komponenta je v pořádku ale padá její test – to je chyba).

Přece nebudu omezovat unittesty jen na věci, které mají mockovatelné závislosti.
Je to naopak, abyste mohl dobře testovat pomocí jednotkových testů, potřebujete mockovatelné závislosti. Samozřejmě, naprasit jde ledacos a také se to děje, ale to už se pak nebavíme o best practices.
Název: Re:Java a statické metody
Přispěvatel: Natix 23. 10. 2015, 11:32:34
https://taskinoor.wordpress.com/2011/09/21/the-abuse-of-design-patterns-in-writing-a-hello-world-program/
Název: Re:Java a statické metody
Přispěvatel: Kit 23. 10. 2015, 14:29:17
Já statické metody neodmítám, napsal jsem myslím docela jasně, kdy je podle mne vhodné je použít. Jinak projevem nepřemýšlení je právě to zneužívání statických metod i tam, kde by měla být volná vazba.
Pokud navrhujete volnou vazbu i pro goniometrické funkce, tak už opravdu netuším, kde by by bylo vhodné použít statické metody.

Volnou vazbu na sinus zde navrhl nějaký příznivce statických metod, aby zjistil, kam až je Filip ochoten zajít. A Filip na to kývl. Proč ne? Pokud dělám program na kalkulačku s goniometrickými funkcemi, tak by se mi tato vazba hodila pro injektáž volané funkce. Jenže je statická a proto ji musím kvůli tomu zbytečně obalovat do dalšího objektu. Také by se mi do ní hodila funkce sin(), která pracuje s úhlovými stupni místo radiánů tak, abych si mohl nějakým radiobuttonem deg/rad/grad za běhu přepínat příslušnou knihovnu.

Citace
Citace
Jenže bez mockování nedokážete otestovat jenom tu jednu komponentu – nanejvýš otestujete komponentu a vše, na čem závisí.
Napřed se otestují závislosti a pak komponenta i se závislostmi? Proč by tohle neměl být unittest? Přece nebudu omezovat unittesty jen na věci, které mají mockovatelné závislosti.

Už jsem viděl dotaz, "proč někomu sin(30) nevrací 0.5". Kdyby si dotyčný napsal test na tuto knihovní funkci, jistě by poznal proč. Obráceně jsou případy, kdy si místo funkce sin() chci namockovat jinou hodnotu, např. 1.5 nebo -4.5, abych si zjistil odolnost navazující jednotky na nesmyslné hodnoty. Bez možnosti mockování by to vůbec nešlo, protože takové hodnoty z funkce sin() nedostanu.
Název: Re:Java a statické metody
Přispěvatel: F. 23. 10. 2015, 14:30:31
Napřed se otestují závislosti a pak komponenta i se závislostmi? Proč by tohle neměl být unittest?
Není to jednotkový test (unit test), protože netestuje jednotku, ale několik jednotek (komponenta a její závislosti). Takové testy také mají smysl, ale jsou komplexnější. A moc pro ně neexistuje nějaká rozšířená podpora, často se k tomu ohýbají nástroje pro jednotkové testy (v Javě JUnit nebo TestNG), ale to nefunguje úplně ideálně. Pak vám třeba při chybě v té závislosti padají i testy závislé komponenty, což je špatně (komponenta je v pořádku ale padá její test – to je chyba).

Přece nebudu omezovat unittesty jen na věci, které mají mockovatelné závislosti.
Je to naopak, abyste mohl dobře testovat pomocí jednotkových testů, potřebujete mockovatelné závislosti. Samozřejmě, naprasit jde ledacos a také se to děje, ale to už se pak nebavíme o best practices.

To jste se dostali k classical and mockist testing, nelze obecne rict ze jedno je lepsi/horsi, dobre/spatne.

http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 23. 10. 2015, 15:22:24

Volnou vazbu na sinus zde navrhl nějaký příznivce statických metod, aby zjistil, kam až je Filip ochoten zajít. A Filip na to kývl. Proč ne? Pokud dělám program na kalkulačku s goniometrickými funkcemi, tak by se mi tato vazba hodila pro injektáž volané funkce. Jenže je statická a proto ji musím kvůli tomu zbytečně obalovat do dalšího objektu. Také by se mi do ní hodila funkce sin(), která pracuje s úhlovými stupni místo radiánů tak, abych si mohl nějakým radiobuttonem deg/rad/grad za běhu přepínat příslušnou knihovnu.

Ale to uz jsou dve uplne jina zadani. Nemluve o tom, ze zadne baleni objektu ani tak nepotrebujes, pokud mas first class funkce.

Citace
Už jsem viděl dotaz, "proč někomu sin(30) nevrací 0.5". Kdyby si dotyčný napsal test na tuto knihovní funkci, jistě by poznal proč. Obráceně jsou případy, kdy si místo funkce sin() chci namockovat jinou hodnotu, např. 1.5 nebo -4.5, abych si zjistil odolnost navazující jednotky na nesmyslné hodnoty. Bez možnosti mockování by to vůbec nešlo, protože takové hodnoty z funkce sin() nedostanu.

Bud tam mas volnou vazbu a pak ma smysl to testovat a muzes to testovat.
Nebo nemas. Pak zase tu vadnou hodnotu dostat ze "sinu" nemuzes a resis imaginarni problem.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 23. 10. 2015, 17:13:32
Bud tam mas volnou vazbu a pak ma smysl to testovat a muzes to testovat.
Nebo nemas. Pak zase tu vadnou hodnotu dostat ze "sinu" nemuzes a resis imaginarni problem.
Kdybych měl pětikorunu za všechny tyhle „nemůžeš“, u kterých se později ukázalo, že „můžeš“, byl bych nejbohatší člověk na světě. To, že jste z vámi používané implementace v současné verzi chybu nevyloudil, neznamená, že se to nemůže stát. Spustíte to na jiném JRE nebo jenom na jiné verzi téhož JRE, a pak to vysvětlujte té výjimce, že tam nemůže vypadnout.
Název: Re:Java a statické metody
Přispěvatel: Radek Miček 23. 10. 2015, 18:22:47
Bud tam mas volnou vazbu a pak ma smysl to testovat a muzes to testovat.
Nebo nemas. Pak zase tu vadnou hodnotu dostat ze "sinu" nemuzes a resis imaginarni problem.
Kdybych měl pětikorunu za všechny tyhle „nemůžeš“, u kterých se později ukázalo, že „můžeš“, byl bych nejbohatší člověk na světě. To, že jste z vámi používané implementace v současné verzi chybu nevyloudil, neznamená, že se to nemůže stát. Spustíte to na jiném JRE nebo jenom na jiné verzi téhož JRE, a pak to vysvětlujte té výjimce, že tam nemůže vypadnout.

Používání standardních typů jako například String nebo int vám nevadí?
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 23. 10. 2015, 18:30:27
Bud tam mas volnou vazbu a pak ma smysl to testovat a muzes to testovat.
Nebo nemas. Pak zase tu vadnou hodnotu dostat ze "sinu" nemuzes a resis imaginarni problem.
Kdybych měl pětikorunu za všechny tyhle „nemůžeš“, u kterých se později ukázalo, že „můžeš“, byl bych nejbohatší člověk na světě. To, že jste z vámi používané implementace v současné verzi chybu nevyloudil, neznamená, že se to nemůže stát. Spustíte to na jiném JRE nebo jenom na jiné verzi téhož JRE, a pak to vysvětlujte té výjimce, že tam nemůže vypadnout.

Takovehle starosti bych fakt chtel mit (nebo asi ne, problemy s overengineeringem jsou pak peklo). Ale kdyz to uz resis, tak stare dobre pravidlo stimulate, don't simulate.

Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 23. 10. 2015, 18:32:15
Ale hlavne nam tu jeste (a opet) dluzis odpovedi, jak bys ve svem fundamentalistickem svete resil nektere celkem bezne problemy.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 23. 10. 2015, 19:03:47
problemy s overengineeringem jsou pak peklo
Co je pekelného na tom, že místo
Kód: [Vybrat]
Transformer.transform(…);

napíšete

Kód: [Vybrat]
private final Transformer transformer;

public X(Transformer transformer) {
  this.transformer = transformer;
}

transformer.transform(…);

?
Název: Re:Java a statické metody
Přispěvatel: JSH 23. 10. 2015, 19:58:38
Co je pekelného ...
Třeba že je najednou ten Transformer součástí rozhraní i když by nemusel? Někdy je to ok, ale na to aby to byla obecná best-practice je tam až moc podmínek.
Název: Re:Java a statické metody
Přispěvatel: Kit 23. 10. 2015, 20:16:44
Používání standardních typů jako například String nebo int vám nevadí?

Docela mi vadí, že třídy String a Integer jsou final. Nemohu je tedy dědit, ale musím je obalit. Snad k tomu měli tvůrci nějaký závažný důvod.
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 23. 10. 2015, 20:21:23
Třeba že je najednou ten Transformer součástí rozhraní i když by nemusel? Někdy je to ok, ale na to aby to byla obecná best-practice je tam až moc podmínek.
Nevidím žádný přínos v tom, že to bude Transformer používat tajně – zato spoustu nevýhod. A když už bych měl pocit, že existuje jenom jediná správná implementace Transformeru, můžu udělat druhý bezparametrický konstruktor, který sám získá tu jedinou správnou implementaci.
Název: Re:Java a statické metody
Přispěvatel: JSH 23. 10. 2015, 20:57:16
Nevidím žádný přínos v tom, že to bude Transformer používat tajně – zato spoustu nevýhod. A když už bych měl pocit, že existuje jenom jediná správná implementace Transformeru, můžu udělat druhý bezparametrický konstruktor, který sám získá tu jedinou správnou implementaci.
Zádný přínos? Takže to že tímhle vytažením zviditelním a tím zabetonuju kus vnitřností nějaké třídy ničemu nevadí? Já si naopak nepamatuju situaci, kdy bych měl potřebu nějaké třídě kecat do toho, jak si uvnitř transformuje data.
Název: Re:Java a statické metody
Přispěvatel: Viky 23. 10. 2015, 21:19:03
Tohle je fakt legrační. Jak hádání se, jestli je lepší psát 5-5 nebo -5+5. Pak někdo přijde s tím, že lepší je 5+(-5) a další, že všichni jsou lamy, jedině ln(1) je správně. Pak někdo opáčí, že nejčistší je to udělat jako ln(-exp(i*pi)).
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 23. 10. 2015, 21:23:21
Tohle je fakt legrační. Jak hádání se, jestli je lepší psát 5-5 nebo -5+5. Pak někdo přijde s tím, že lepší je 5+(-5) a další, že všichni jsou lamy, jedině ln(1) je správně. Pak někdo opáčí, že nejčistší je to udělat jako ln(-exp(i*pi)).

Ne, tady jde o to, jak lepit dohromady programy, co nechavat napevno, co menitelne a jak to testovat.
Název: Re:Java a statické metody
Přispěvatel: BoneFlute 23. 10. 2015, 23:30:44
Zádný přínos? Takže to že tímhle vytažením zviditelním a tím zabetonuju kus vnitřností nějaké třídy ničemu nevadí? Já si naopak nepamatuju situaci, kdy bych měl potřebu nějaké třídě kecat do toho, jak si uvnitř transformuje data.

No, tohle je za celé vlákno jediná zajímavá poznámka.

Je pravda, že do toho mohu vstříknout objekt, který bude mět sice naprosto stejnou signaturu, ale zcela jiné chování. Jenže, opravdu?

Funkce sin() vždycky vrátí číslo. Můžu nějak záviset na tom, zda to číslo bude platné? (Skutečnost, že díky neplatnému sin() nemůžu očekávat platné hodnoty volajícího je samozřejmá.)
Když mi bude funkce vracet pole, a to pole nebude obsahovat správné hodnoty, tak by mi signatura měla zajistit, že to celé nerozbije, ale, že to bude počítat špatně, to je očekávatelné. Součást signatury je neurčitelnost, kolik návratových hodnot mi to v tom poli vrátí. Takže to musím doladit ifama.

Na druhou stranu, pokud defaultní implementace je řešená s chybou, tak tu chybu nemohu opravit, protože tato třída na tom závisí, a já nemohu vědět, zda o té chybě volající ví, nebo ne.

Zajímavé.
Název: Re:Java a statické metody
Přispěvatel: zboj 24. 10. 2015, 00:15:36
Tohle je fakt legrační. Jak hádání se, jestli je lepší psát 5-5 nebo -5+5. Pak někdo přijde s tím, že lepší je 5+(-5) a další, že všichni jsou lamy, jedině ln(1) je správně. Pak někdo opáčí, že nejčistší je to udělat jako ln(-exp(i*pi)).

Ta poslední varianta je nejhezčí, říkal to nějaký Euler :)
Název: Re:Java a statické metody
Přispěvatel: balki 24. 10. 2015, 01:25:10
Pridam sa aj ja k mudrovaniu. Toto bola, jedna z otazok, co som si kladol. Ci je vyhodnejsie pouzivat singleton, alebo staticke metody.

Nevyhoda je statickych metod je v tom, ze ich nejde prekonavat (override), a viazu sa na triedu, nie na instanciu. Pokial viem, ze pouzijem vsate rovnaku implementaciu,  staticka metoda staci. Singleton je sikovnejsi, ked som si nie celkom isty, ci nebudem potrebovat viac instancii nabuduce, pripadne pozmenit spravanie.  Proste  prepisem factory method a instancujem tak ako zrovna potrebujem. Pripadne, ak viem, ze mozno budem tu metodu predavat ako parameter. (Presnejsie povedane, objekt, ktoremu patri)

Vhodne pouzitie statickych metod su bezstavove metody, ktore proste zoberu vstup, daju vystup.   
Název: Re:Java a statické metody
Přispěvatel: Filip Jirsák 24. 10. 2015, 07:22:24
Vhodne pouzitie statickych metod su bezstavove metody, ktore proste zoberu vstup, daju vystup.
Podle mne je tam ale velmi podstatné to „prostě“. Pokud ta statická metoda má triviální kód a je v podstatě náhradou céčkového makra, není důvod nepoužít statickou metodu. Pokud je ten kód složitější nebo se tam volají jiné služby, nedá se vyloučit, že ten kód někdy bude potřeba pozměnit. Aby to nedospělo k tomu, že ta statická metoda bude v různých variantách rozkopírována po celém programu.
Název: Re:Java a statické metody
Přispěvatel: Franta <xkucf03/> 24. 10. 2015, 13:20:25
Používání standardních typů jako například String nebo int vám nevadí?
Docela mi vadí, že třídy String a Integer jsou final. Nemohu je tedy dědit, ale musím je obalit. Snad k tomu měli tvůrci nějaký závažný důvod.

Co třeba STFW? :-) Hned první odkaz: Why is String class declared final in Java? (https://stackoverflow.com/questions/2068804/why-is-string-class-declared-final-in-java)

Neměnné objekty mají řadu výhod a dost usnadňují práci. Naopak kdyby šlo obsah Stringu měnit, tak by to vedlo k dost nevyzpytatelnému chování a programy by byly dost nespolehlivé – resp. musel by sis všechny vstupní parametry okopírovat do vlastního objektu, abys měl jistotu, že ti nikdo nebude měnit ty hodnoty pod rukama. Hodně lidí by se střelilo do nohy (asi jako v případě statických lokálních proměnných (https://blog.frantovo.cz/c/352/Opravujeme%20chyby%20v%C2%A0softwaru%3A%20inotify-tools)).

Pokud chceš obsah měnit, tak používej StringBuilder/StringBuffer. Pokud chceš přidávat chování, obal to vlastní třídou. Pro čísla platí totéž.
Název: Re:Java a statické metody
Přispěvatel: zboj 24. 10. 2015, 13:59:35
Používání standardních typů jako například String nebo int vám nevadí?
Docela mi vadí, že třídy String a Integer jsou final. Nemohu je tedy dědit, ale musím je obalit. Snad k tomu měli tvůrci nějaký závažný důvod.

Co třeba STFW? :-) Hned první odkaz: Why is String class declared final in Java? (https://stackoverflow.com/questions/2068804/why-is-string-class-declared-final-in-java)

Neměnné objekty mají řadu výhod a dost usnadňují práci. Naopak kdyby šlo obsah Stringu měnit, tak by to vedlo k dost nevyzpytatelnému chování a programy by byly dost nespolehlivé – resp. musel by sis všechny vstupní parametry okopírovat do vlastního objektu, abys měl jistotu, že ti nikdo nebude měnit ty hodnoty pod rukama. Hodně lidí by se střelilo do nohy (asi jako v případě statických lokálních proměnných (https://blog.frantovo.cz/c/352/Opravujeme%20chyby%20v%C2%A0softwaru%3A%20inotify-tools)).

Pokud chceš obsah měnit, tak používej StringBuilder/StringBuffer. Pokud chceš přidávat chování, obal to vlastní třídou. Pro čísla platí totéž.

Stačilo by mít něco jako MutableString. Měnitelnost instancí hezky řeší ObjC. V C++ to mají podobně, sice třeba std::string se dá měnit, ale při práci s kolekcemi se na klíče dělá standardně CoW.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 24. 10. 2015, 15:14:12
Stačilo by mít něco jako MutableString. Měnitelnost instancí hezky řeší ObjC. V C++ to mají podobně, sice třeba std::string se dá měnit, ale při práci s kolekcemi se na klíče dělá standardně CoW.

Nemas snad StringBuilder? Nastesti se neda moc dobre pouzivat tam, kde String.



Btw: nemichal bych tu moc final ve smyslu "nelze podedit" s immutable objekty. To spolu souviset muze a nemusi.
Název: Re:Java a statické metody
Přispěvatel: zboj 24. 10. 2015, 15:38:22
Stačilo by mít něco jako MutableString. Měnitelnost instancí hezky řeší ObjC. V C++ to mají podobně, sice třeba std::string se dá měnit, ale při práci s kolekcemi se na klíče dělá standardně CoW.

Nemas snad StringBuilder? Nastesti se neda moc dobre pouzivat tam, kde String.



Btw: nemichal bych tu moc final ve smyslu "nelze podedit" s immutable objekty. To spolu souviset muze a nemusi.
StringBuilder je něco úplně jiného, odpovídá stringstream a používá se v jiných případech než měnitelný řetězec.
Název: Re:Java a statické metody
Přispěvatel: Kit 24. 10. 2015, 16:06:04
Docela mi vadí, že třídy String a Integer jsou final. Nemohu je tedy dědit, ale musím je obalit. Snad k tomu měli tvůrci nějaký závažný důvod.
Neměnné objekty mají řadu výhod a dost usnadňují práci.[/url]).

Neměl jsem na mysli finální objekty (ty mi naopak vyhovují), ale finální třídy. Nemohu například napsat

Kód: [Vybrat]
class Jmeno extends String { ...
Název: Re:Java a statické metody
Přispěvatel: perceptron 24. 10. 2015, 16:54:12
Citace
Neměl jsem na mysli finální objekty (ty mi naopak vyhovují), ale finální třídy. Nemohu například napsat
final String znamena ochranu pred Kitom ktory oddedi od zakladnej immutable datovej struktury, urobi z nej mutable a zachrani projekt
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 24. 10. 2015, 17:16:14
Citace
Neměl jsem na mysli finální objekty (ty mi naopak vyhovují), ale finální třídy. Nemohu například napsat
final String znamena ochranu pred Kitom ktory oddedi od zakladnej immutable datovej struktury, urobi z nej mutable a zachrani projekt

Takze je to navrzene dobre.
Název: Re:Java a statické metody
Přispěvatel: Kit 24. 10. 2015, 17:34:38
Citace
Neměl jsem na mysli finální objekty (ty mi naopak vyhovují), ale finální třídy. Nemohu například napsat
final String znamena ochranu pred Kitom ktory oddedi od zakladnej immutable datovej struktury, urobi z nej mutable a zachrani projekt

Takze je to navrzene dobre.

Kecá. Téměř všechny proměnné mám immutable a nevidím důvod, proč bych měl zrovna objekt třídy String modifikovat. Nejde to, takže třídu String dál obaluji.
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 24. 10. 2015, 17:39:08

Kdyz uz ses nam tu tak rozpovidal, cekaji na tebe jeste nezodpovezene otazky od minule...
Název: Re:Java a statické metody
Přispěvatel: perceptron 24. 10. 2015, 17:47:36
naco chcete dedit od stringu ked ho nechcete modifikovat?
Název: Re:Java a statické metody
Přispěvatel: Ondra Satai Nekola 24. 10. 2015, 17:55:10
naco chcete dedit od stringu ked ho nechcete modifikovat?

Dovedu si predstavit, ze by do nej nekdo chtel dat nejake dalsi metody, ale prijde mi to obecne jako dost problematicky napad.
Název: Re:Java a statické metody
Přispěvatel: perceptron 24. 10. 2015, 18:27:24
este mi pride ze mozno kit chce vlastne typedef

mne sa zda ze immutable string je designove rozhodnutie po skusenostiach z c++ kde kazdy projekt vymyslel vlastny genialny string.