Java a statické metody

Natix

Re:Java a statické metody
« Odpověď #30 kdy: 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.


F.

Re:Java a statické metody
« Odpověď #31 kdy: 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.

Re:Java a statické metody
« Odpověď #32 kdy: 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.

Kit

Re:Java a statické metody
« Odpověď #33 kdy: 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.

Re:Java a statické metody
« Odpověď #34 kdy: 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.


Kit

Re:Java a statické metody
« Odpověď #35 kdy: 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? :)

F.

Re:Java a statické metody
« Odpověď #36 kdy: 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?

Kit

Re:Java a statické metody
« Odpověď #37 kdy: 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.

Re:Java a statické metody
« Odpověď #38 kdy: 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ů.

Re:Java a statické metody
« Odpověď #39 kdy: 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.

k

Re:Java a statické metody
« Odpověď #40 kdy: 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 :)

Kit

Re:Java a statické metody
« Odpověď #41 kdy: 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ě.

Re:Java a statické metody
« Odpověď #42 kdy: 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.

JSH

Re:Java a statické metody
« Odpověď #43 kdy: 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.

k

Re:Java a statické metody
« Odpověď #44 kdy: 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.