Python týden Geek tričko zdarma
Tričko zdarma! Stačí před dobitím bodů použít kód TRIKO15. Více informací zde
Pouze tento sleva až 80% na kurzy Python

STUPID - Špatné praktiky vývoje softwaru

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Již jsme si zmínili ty nejlepší praktiky pro vývoj softwaru, které sdružuje akronym SOLID. Podobně existuje i opačný akronym, STUPID, který naopak sdružuje špatné praktiky, chyby a antipatterny, které vedou k plýtvání časem i penězi.

Skupina praktik STUPID se skládá z:

  • Singleton
  • Tight coupling
  • Untestability
  • Premature optimization
  • Indescriptive naming
  • Duplication

Pojďme si je podrobně vysvětlit.

Singleton

STUPID začíná hned kontroverzním jedináčkem, který středně pokročilí programátoři používají a ti profesionální jej zatracují.

Singleton a koťátka

Pokud chcete porušovat LoD, Shy, Loose coupling, DIP, IoC a řadu dalších dobrých praktik, sdílejte závislosti ve svých aplikacích přes antipattern Singleton. I přes prvotní senzaci kolem Singletonu se časem zjistilo, že to není v jádru nic jiného, než globální proměnná, oblečená do hezkého obleku návrhových vzorů. A samozřejmě přináší ty samé problémy jako globální proměnné. Závislosti budou globálně dostupné a budou porušovat základní stavební kameny OOP. Bohužel slýchávám, že se na Singletony ptají na některých pracovních pohovorech a snad je i používají ve svém firemním softwaru. Buďte tedy u pohovorů opatrní a snažte se vzor popisovat neutrálně. Ve svých aplikacích jej ale nepoužívejte, na světe bude méně zla.

Tight coupling

Vytvářejte ve své aplikaci těsné vazby, např. výše zmíněnými Singletony nebo špatným rozdělením odpovědnosti, nepoužívejte GRASP, a vaše aplikace brzy přestanou být udržovatelné. Těsné vazby označují situaci, kdy je mezi dvěma třídami zbytečné množství vazeb. Celý systém je potom svázaný těsně k sobě, což znemožňuje jeho modifikaci a znesnadňuje jeho rozšiřování. Opakem je již míněný loose nebo low coupling, kdy jsou komponenty volně pospojované jen několika vazbami mezi sebou.

Untestability

Netestovatelnost se týká automatických testů, o kterých zde máme v každém jazyce samostatný kurz. Pokud jste se o testování ještě nezajímali, určitě jej doporučuji nastudovat. Při návrhu tříd je nutné pamatovat na to, že třídu bude pravděpodobně někdo testovat. Je to podobné, jako bychom měli pamatovat na to, že třídu bude pravděpodobně někdo dědit. Pokud budete používat např. Singletony, znemožníte mockování závislostí a tím i testování třídy (to je mimochodem jedna z dalších nevýhod jedináčků). Dalším problémem může být nedodržování SRP, kdy jsou metody příliš dlouhé, vágní, např. místo vrácení hodnoty něco vypisují a podobně. Takový kód potom testovat moc dobře nelze. A komplexní aplikace bez alespoň základních automatických testů je v dnešní době již nekonkurences­chopná, náklady na ruční testování reálných komerčních aplikací jsou poměrně vysoké. Spoustu informací o testování včetně úvodu a výčtu výhod a nevýhod viz již zmíněné kurzy o testování v sekcích příslušných programovacích jazyků zde na síti.

Premature optimization

Co se týká předčasné optimalizace, možná jste někdy zaslechli větu

Premature optimization is the root of all evil

, tedy "Předčasná optimalizace je kořenem veškerého zla." Poučka říká, že bychom se neměli zabývat optimalizací kódu, dokud to není opravdu potřeba. Poměrně krátce se totiž zjistilo, že před nasazením aplikace do reálného produkčního prostředí nemůžeme tušit, jak na tom bude výkonově a kde přesně budou tzv. úzká hrdla (bottlenecks). Optimalizace, které programátoři zbrkle provedli, v naprosté většině pouze zpomalily vývoj a v praxi nebyly potřeba nebo nebyly dostatečné. Poučka nám ale naopak neříká, abychom psali nekvalitní kód. Měli bychom volit správná a jednoduchá řešení a až při jejich selhání provést optimalizaci. Při jednom z našich IT školení proběhla zajímavá debata o volbě datových typů proměnných. Jeden z účastníků se ohradil proč doporučujeme používat pro reprezentaci všech čísel typ int, když např. věk uživatele nebude nikdy více než 150 let a int má rozsah do 2 miliard. Naší odpovědí bylo, že int v paměti zabírá akorát 32 bitů a proto s ním 32/64 bitový procesor pracuje mnohem rychleji, než by pracoval s 8 bitovým menším typem. Tato optimalizace by tedy byla pravděpodobně výkonově nevýznamná a podobné rozmýšlení zbytečně plýtvá vývojový čas. O optimalizaci aplikací připravujeme samostatný kurz.

Indescriptive naming

Jedna ze začátečnických chyb je používání nicneříkajících názvů, ať již proměnných, metod nebo tříd. Mít třídu v množném čísle nedává smysl, metoda by měla byt v rozkazovacím způsobu, tedy utoc(), nikoli utok(), což by se mohlo plést s proměnnou utok, obsahující např. útok bojovníka v HP. Někteří proměnné pojmenovávají dokonce jako x, pole, text a podobně. Nebo jako foo, bar, baz, to bohužel naleznete např. v ukázkách oficiálního PHP manuálu. Proměnné pojmenováváme vždy podle toho, co obsahují, je to naprosto jednoduché pravidlo a překvapivě mnoho začátečníků jej porušuje. Správné názvy jsou tedy např. soucet, nadpis, faktury. Zamyslete se nad rozdílem mezi polem pole a polem faktury. Kolekce pojmenováváme samozřejmě v množném čísle, pole faktur se nesmí jmenovat ani faktura ani f. Používání podobných identifikátorů extrémně zpomaluje vývoj aplikace a jelikož programátoři běžně pobírají až 4 průměrné platy, značte zdražuje i její vývoj.

Duplication

O duplicitním kódu a DRY jsme již mluvili. Jakýkoli kód, který se nachází ve stejné nebo i jen podobné podobě na více místech aplikace, je automaticky špatně a představuje potenciální hrozbu pro další vývoj. Nejen, že se v dlouhém kódu špatně orientuje, ale každou změnu je nutné provést na všech výskytech podobného kódu a to je prostor pro zanesení chyb. Vyčerpávající příklad jak lze kód zkrátit pomocí pravidel DRY a KISS naleznete v článku Základní best practices pro návrh softwaru.


 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
11 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Předchozí článek
Praktiky SOLID
Všechny články v sekci
Best practices pro návrh softwaru
Aktivity (2)

 

 

Komentáře

Avatar
Martin Dráb
Redaktor
Avatar
Martin Dráb:30.9.2017 12:10

Tato optimalizace by tedy byla pravděpodobně výkonově nevýznamná a podobné rozmýšlení zbytečně plýtvá vývojový čas.

Na ia32/AMD64 je to spíš tak, že taková optimalizace by z hlediska výpočtů neušetřila nic (nebude moc instrukcí, které umějí počítat s 8bitovými hodnotami, ale ne s 32bitovými). A samozřejmě sčítačky, násobičky a podobné jednotky budou mít v procesoru 32/64bitovou šířku.

Čistě teoreticky by taková optimalizace mohla ušetřit prostor v registrech, což znamená méně přístupů do paměti, a tedy méně výpadků cache, a tak větší výkon. Pokud vím, překladače (do nativního kódu) ale takto neoptimalizují; i proto, že už tak musí při překladu/opti­malizacích řešit dostatek NP úplných a algoritmicky nerozhodnutelných problémů. Tzn. nebudou strkat více proměnných do jednoho velkého registru najednou.

Odpovědět  +1 30.9.2017 12:10
2 + 2 = 5 for extremely large values of 2
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 9:42

Myslím, že při výuce best practices by se hlavně měla zdůraznit jedna věc - dbát na best practices, ale vždy se zachovat dle situace a nebrat vše dogmaticky. Někdy slepé následování těchto pouček může vytvořit kód, který sice všechny splňuje, ale nikdo se v něm nevyzná. Souvisí to i s tím, že spousta pouček jde částečně proti sobě (např. KISS a DRY). Proto bych byl opatrný s výrazy "Singleton nikdy nepoužívejte" nebo "jakýkoliv výskyt dvou stejných kusů kódu je automaticky špatně. Obvykle to tak je, ale ne vždy, proto je důležitější se nad daným problémem vždy zamyslet :-)

 
Odpovědět  +3 2.10.2017 9:42
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 10:15

Takovéhle komentáře nejsou moc přínosné, protože jen zavádíš nějaká tvrzení bez žádných podkladů. Můžeš nám uvést konkrétní případ, kdy dává smysl mít v programu 2 stejné kusy kódu? Oni ti to lidé olajkují, protože svůj kód samozřejmě prasí a tak mají radost, že někdo říká, že to není tak horké. Já si myslím, že to je tak horké. Singleton zde pomlouvám z hlediska předávání závislostí, kde je to opět IMHO na 100% antipattern. Když tam dáš obyčejnou globální proměnnou, bude to dělat to samé. Když něco takového tvrdíš, můžeš prosím uvést nějaké příklady?

Odpovědět  +1 2.10.2017 10:15
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
Martin Dráb
Redaktor
Avatar
Odpovídá na David Čápka
Martin Dráb:2.10.2017 10:41

Máš teoreticky pravdu, ale porušení best practices se týká dosti specifických případů a pro začátečníky/po­kročilejší programátory je dobré volit v podstatě dogmatický přístup. Ušetří si tím problémy. Časem přijdou na to, kdy se drobné porušení best practices vyplatí. Ale jedná se podle mě o tak vzácné případy, že se s nimi, zejména v čistě OOP světě, málokdy setkají.

můžeš prosím uvést nějaké příklady?

Například optimalizace cílené na extrémní výkon. Překladač je zvládá taky, ale někdy je třeba mu trošku pomoci. Příkladem je třeba snížení počtu iterací v cyklu for (má za následek několikeré zkopírování těla).

Obecně ale optimalizace pro výkon jdou proti best practices/čitel­nosti kódu. Ale jak říkám, vidí se to velmi velmi zřídka.

Odpovědět  +1 2.10.2017 10:41
2 + 2 = 5 for extremely large values of 2
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 11:31

Je třeba se zamyslet nad tím, jestli stejný nebo podobný kód opravdu reprezentuje jedno chování, anebo jestli to jsou dvě nezávislé věci, které vypadají v současnosti stejně. Můžu třeba mít dvě obrazovky, které se v současnosti chovají v určité části stejně, ale vím, že jsou na sobě nezávislé a že v budoucnu když jednu upravím, tak by ta změna neměla ovlivnit tu druhou, proto nedává smysl ten stejný kód sjednocovat. Neříkám, že je to častý případ :-)

Další věc, s kterou se často setkávám, a která je dle mě nebezpečnější, je to, že kvůli dogmatickému dodržování DRY se programátoři snaží znovuvyužívat kód co nejvíce to jde, bohužel často formou dědičnosti, která s sebou často nese problémy (místo kompozice a delegování, které bohužel většina jazyků neumí automaticky).

Co se týče Singletonu, tak DI je sice krásný princip, ale pokud víte, že danou funkcionalitu nemá smysl mockovat ani testovat, a singleton neuděláte statickou třídou, ale instancí, ke které je statický přístup (aby to šlo případně jednoduššeji změnit), tak to může být jednodušší než si přes 5 tříd předávat závislosti (např. nějaké hodně basic helper metody). Hlavní je třeba si to promyslet a zvážit výhody, ne slepě aplikovat poučku.

Shrnul bych to tak, že důležité je pochopit PROČ daný practice používat, jaký problém řeší a jaké má výhody/nevýhody. Slepé následování pouček z internetu není podle mě to pravé, to jsem chtěl tím komentářem říct :-) Tím nechci článek shazovat, líbí se mi.

P.S. optimalizace jsou kapitola sama pro sebe, u těch se často na návrhové vzory musí zapomenout, o těch jsem se tedy nebavil

 
Odpovědět 2.10.2017 11:31
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 11:39

O problematice dědičnosti jsem v těchto několika nových článcích mluvil a naprosto s tebou souhlasím, že není vždy ideální. Z toho ovšem nevyplývá, že by se DRY nemělo dělat dogmaticky, ale že se u něj musí přemýšlet. Ten příklad, který si uvedl, mi nepřijde moc dobrý. Pro obrazovky přímo dává smysl vyčlenit nějakou sdílenou funkcionalitu, nedokáži si představit případ kdy by to tak nebylo a jsi se konkrétnímu příkladu také vyhnul, asi ze stejného důvodu.

Ohledně DI s tebou opět souhlasím, ale zas nesouhlasím s tím, co z toho podle tebe vyplývá. Když nechceš dělat DI, což dává smysl, protože udělat DI je poměrně složité, pokud není k dispozici od nějakého frameworku, je mnohem lepší použít statické třídy nebo statické atributy (např. v místním e-shopu jsem měl něco jako SpravceUzivatelu::$uzivatel). Singleton je nebezpečný v tom, že si lidé myslí, že je správně. Je to přeci návrhový vzor. Ale on není správně, proto to dávám tak nekompromisně najevo.

Odpovědět  +1 2.10.2017 11:39
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 11:53

Já nepsal, že DI nepoužívat, já tí myslel, že se to dá kombinovat, DI použít na opravdové závislosti a statický přístup na věci, které by kód zbytečně zkomplikovaly a neposkytly žádnou výhodu. Výhoda DI je v testovatelnosti a zaměnitelnosti závislostí. Pokud přes DI nainjektuji něco, co vím, že nejde nebo nemá smysl testovat a nebude existovat více implementací, tak jsem si tím zkomplikoval kód (pokud to injektujipřes hierarchii x tříd) a nedostal jsem za to žádnou výhodu. To je právě ta situace, kdy je třeba se zamyslet. Návrhový vzor není správný nebo špatný, pouze jeho použití je správné nebo špatné. Já tvrdím, že lze správně použít Singleton a špatně použít DI (i když v 99.99% je to naopak a singleton by zdaleka neměl být prvním nápadem k vyřešení problému).

K té obrazovce: např. po otevření zobrazuji notifikaci nebo něco podobného.
V kódu obou dvou mám
a()
b()
c()
Je to stejný kód? Ano. Měl by se extrahovat do metody/třídy a tu použít z obou obrazovek? Ano, pokud ta metoda bude vyjadřovat společné chování a její změna má ovlivnit všechny obrazovky, které jej používají. Ne, pokud ty obrazovky jsou nezávislé, a pouze TEĎ (třeba na začátku projektu) se chovají stejně, ale tuším, že v budoucnu se změní a to nezávisle na sobě. Zase může být lepší to vyextrahovat a v případě změny to zase rozdělit na více metod nebo nakopírovat zpátky, ale když vím, že je pravděpodobné, že v budoucnu dojde ke změně, tak to je práce navíc.

 
Odpovědět 2.10.2017 11:53
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 11:58

Pak jsi asi nepochopil princip DI. Jakmile si jednou napíšeš kontejner, je předávání závislostí jednodušší, než Singleton, a úplně stejně složité jako statika obecně. DI nemá smysl s ničím kombinovat, protože je nejsprávnější z hlediska návrhu a zároveň nejjednodušší na použití. Jediný háček je v tom, že je složité napsat ten kontejner, proto to tolik lidí prasí bez ní.

K těm obrazovkám, jak říkáš, mně přijde lepší to teď spojit a rozdělit případně v budoucnu. Nechávat takovéhle věci v kódu je IMHO koledování si o chyby.

Odpovědět 2.10.2017 11:58
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 12:06

Tak DI kontejner z PHP, ze kterého se tahají věci přes string (což je pro mě trochu prasárna, kterou jde jen složitě staticky kontrolovat, ale zase chápu, že pro use case PHP se to hodí) je rozdíl oproti DI, kde všechno předáváš konstruktory, tam ti ty některé závislosti můžou zbytečně zkomplikovat kód (bavím se spíše v kontextu staticky typovaných jazyků). Souhlasím, že v případě kontejneru nebo field injection je statický přístup zbytečný, pokud nevadí to, že daná třída bude o DI vědět.

 
Odpovědět 2.10.2017 12:06
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 12:35

PHP nemá žádný výchozí DI kontejner, pokud jsi někde viděl tahat služby z kontejneru přes string, tak to není DI, ale service locator. Jak jsem psal, podívej se blíže na princip DI, je to IoC, to I je Inversion a označuje, že ty nic odnikud netaháš, ale je ti to samo vkládáno, třeba přes konstruktor, což je pak 100% OOP a navíc bez práce.

Odpovědět 2.10.2017 12:35
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 12:44

Ano, bavil jsem se o service locatoru, který se v tom kontextu taky často používá v PHP, tam Singleton nemá smysl, u injektování přes konstruktor jsem právě předtím zmiňoval situaci, kdy je to někdy zbytečné. "Bez práce" tedy není vždycky pravda. Ale to je asi fuk, tady ten článek je trochu o něčem jiném, svou myšlenku jsem předal :-)

 
Odpovědět 2.10.2017 12:44
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 12:47

Tady je taková hezká sada pravidel, je to všechno o tom kompromisu mezi body 1 a 2 :-)

 
Odpovědět 2.10.2017 12:47
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 21:20

Mně přijde, že se nějak míjíme :) S tím odkazem a body 1 a 2 opět souhlasím. Člověk to musí hlavně nějak udělat, časem je ale dobrý řešit jestli to dělá dobře. To byl třeba dlouho můj problém, protože jsem neměl dobré materiály a myslel si, že když něco funguje, tak to nemusím řešit. Místo toho jsem řešil spoustu problémů, které jsem mít nemusel. Přijde mi, že už se opakuji, když napíši, že Singleton je návod jak dělat něco špatně a proto je špatný. Moc nevím, kde vidíš problém s injektováním do konstruktoru. Prostě napíši:

class A {

        private B b;

        public A(B b) {
                this.b = b;
        }
}

To je celé předání závislosti za předpokladu, že je k dispozici DI kontejner. Nepřipadá mi to ani zbytečné, ani pracné. Je to naopak přirozené a jednoduché. Bavíme se o tom samém? Instance B bude do A automaticky vložena ve chvíli, kdy kontejner vytvoří instanci A.

Odpovědět 2.10.2017 21:20
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 21:46

Jasně, DI je super a tohle je velmi čistý přístup.
Když ale v rootu DI vytváříš třídu A, která vytváří třídu B, která vytváří třídu C, ..., F, G atd., tak pokud ty vnitřní třídy potřebují závislosti, tak jim je musíš z rootu předat a upravit tak konstruktory všech tříd A->G, a drobné změny pak vyžadují úpravy na hodně místech.
Ne všechny třídy jde vytvářet přímo z rootu DI.
Samozřejmě i tohle se dá řešit i jiným způsobem, ale o to mi až tak nešlo.

Singleton je v naprosté většině případů používán nevhodně a neměl by být určitě doporučován jako řešení pro získání závislostí, ale pořád si myslím, že bychom neměli vyučovat programování ve stylu tohle nikdy nepoužívejte/tohle vždycky používejte.
Taky můžu říct nepoužívejte OOP, protože kvůli mutacím limituje paralelizaci, vznikají v něm těžko laditelné chyby, řešením je tedy na vše použít FP x)
Abych tohle obhájil, tak dělám ďáblova advokáta triviálně jednoduchému singletonu, který je samozřejmě téměř vždy chybou. Ale pokud appka je miniaturní, na jedno použití nebo je závislost banální a jiný způsob by příliš zkomplikoval aplikaci? Proč ho nepoužít, aby to bylo více KISS. I když je to stupidní vzor.

Singleton je jen příklad, ale hlavní je donutit se přemýšlet nad výhodami/nevýhodami konkrétního řešení a nesnažit se na všechny situace automaticky najít/aplikovat nějaký návrhový vzor nebo naroubovat řešení, které všechno překomplikuje. Vymýšlení vrstev abstrakcí a indirekcí může někdy být stejně škodlivé jako Knuthova "premature optimization". Neobhajuji Singleton, jen se mi nelíbila ta dogmata v článku :-)

 
Odpovědět 2.10.2017 21:46
Avatar
Petr Nymsa
Redaktor
Avatar
Odpovídá na berykubik
Petr Nymsa:2.10.2017 22:43

Když ale v rootu DI vytváříš třídu A, která vytváří třídu B, která vytváří třídu C, ..., F, G atd., tak pokud ty vnitřní třídy potřebují závislosti, tak jim je musíš z rootu předat a upravit tak konstruktory všech tříd A->G, a drobné změny pak vyžadují úpravy na hodně místech.

Tenhle problém způsobí hodně použitá dědičnost a podle mě to signalizuje moment "jestli by tohle nešlo udělat i jednoduššeji". Jestli-že i třída sama o sobě potřebuje spoustu závislostí tak toho pravděpodobně dělá víc než by měla.

Odpovědět 2.10.2017 22:43
Pokrok nezastavíš, neusni a jdi s ním vpřed
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 22:50

Tak nemusí to být jen dědičností, komplikovaná doména může znamenat komplikovanou funkcionalitu a závislosti.
Správce sešny -> user -> objednávky -> den -> jídlo -> produkty -> .. (ukázkový chain, kde dědičnost nefiguruje, ale hloubka je velká).
Tady pak jde o to dobře skloubit SRP s doménou, aby to z obou pohledů dávalo smysl.

Anyway, myslím, že Martin Dráb naši debatu vyřešil dříve, než začala :-) Tak už to nechme plavat.

Máš teoreticky pravdu, ale porušení best practices se týká dosti specifických případů a pro začátečníky/po­kročilejší programátory je dobré volit v podstatě dogmatický přístup. Ušetří si tím problémy. Časem přijdou na to, kdy se drobné porušení best practices vyplatí.

 
Odpovědět 2.10.2017 22:50
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 23:08

Když ale v rootu DI vytváříš třídu A, která vytváří třídu B, která vytváří třídu C, ..., F, G atd., tak pokud ty vnitřní třídy potřebují závislosti, tak jim je musíš z rootu předat a upravit tak konstruktory všech tříd A->G, a drobné změny pak vyžadují úpravy na hodně místech.

Tady je vidět, že prostě nechápeš co je DI. Nic takového dělat nemusíš. Ten komentář Petra je také nesmysl, hovořilo se o skládání, ne o dědičnosti. Přečtěte si ten kurz, od toho tu je: https://www.itnetwork.cz/…cy-injection

Jinak ten tvůj příklad by vypadal takhle:

class A {

        private B b;

        public A(B b) {
                this.b = b;
        }
}

class B {

        private C c;

        public B(C c) {
                this.c = c;
        }
}

// a tak dále...

class Z {

        private Whatever whatever;

        public Z(Whather whatever) {
                this.whatever = whatever;
        }

}

Jak vidíš, žádné konstruktory upravovat nemusím, vše se dělá samo. To je proto, že ani žádné nevolám. Já jen deklaruji, nevytvářím. DI není o tom, že se něco manuálně předává. Vůbec nevíte, o čem mluvíte, přečtěte si ten kurz, pak se o tom můžeme pobavit.

Odpovědět 2.10.2017 23:08
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 23:17

Chápu, že už tě nebaví se mnou debatovat celý den, ale nepiš prosím automaticky, že DI nerozumím, spíše si nerozumíme v tom, o čem vlastně debatujeme :-) DI používám a troufám si říct, že jeho princip chápu (není to ostatně nic světoborného). O to důležitější je řešit případy, kdy má drobné nevýhody. Neexistuje vzor (ani sada vzorů), které by univerzálně řešily všechny problémy a neměly žádné nevýhody. Pokud by tomu tak bylo, tak by byl vyřešen softwarový návrh.

Tvůj příklad je samozřejmě triviální, já jsem měl na mysli něco ve smyslu tohoto:

class A(B b)
{
      // tady vytvarim instanci C (ano, instance se někdy musí vytvářet i při použití DI :-) )
      // C vytvoří D, to E atd.
      // G bude potřebovat závislost B, tím pádem musím do rootu (A) nainjektovat B, a předat B do C, D, E až G
}

Opět neříkám, že je to častá situace nebo že se to nedá řešit jinak, nechtěl jsem se bavit o konkrétních vzorech, už mi i dochází nápady, kdy je Singleton k něčemu a kdy DI může mít nevýhody, protože takových situací moc není :-) Ale je třeba vždy vážit výhody a nevýhody. Pokud nevím, proč používám konkrétní řešení, co mě to stojí a co mi to dá na oplátku, tak to řeším špatně.

Editováno 2.10.2017 23:18
 
Odpovědět 2.10.2017 23:17
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 23:25

Ještě mi došlo, že tady trošku hapruje názvosloví, i když se to někdy zaměňuje, tak ty se bavíš čistě o injekci (DI), já se bavil spíše obecně o IoC, kde DI obstará root, ale zbytek se musí udělat růčo, což může vést k tomu "problému", který jsem naznačil.

 
Odpovědět 2.10.2017 23:25
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:2.10.2017 23:27

Nevím, co myslíš "rootem DI", takový pojem neznám. DI ti předává závislosti v celé aplikaci. Možná myslíš, že DI funguje v rootu aplikace a další třídy mimo root si předávají závislosti samy. To sice ano, ale to jsou typicky jen malé třídy, ten celek skládáš prostě v rootu, tam máš tu hierarchii a tam je zase DI. Promiň, ale co píšeš mi vážně nedává smysl. Asi toho nechme, půjdu raději spát :)

Odpovědět 2.10.2017 23:27
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
berykubik
Redaktor
Avatar
berykubik:2.10.2017 23:38

To sice ano, ale to jsou typicky jen malé třídy, ten celek skládáš prostě v rootu, tam máš tu hierarchii a tam je zase DI.

Malé nebo velké třídy, i ty potřebují závislosti.. pomocí DI si pohodlně vytvoříš vrchní level (tomu říkám root), kde jsou typicky různí správci a podobné třídy, ale když pak někde potřebuješ vytvořit seznam objednávek, v seznamu vytvořit objekty reprezentující nějakou doménovou věc (třeba to jídlo, jak jsem předtím psal), tak i těmto třídám musíš předat závislosti a to už se musí dělat ručně (pokud je dodrženo IoC).
Proto u banálních závislostí může celý kód zjednodušit přistupovat k něčemu "natvrdo".
Poruší to spoustu principů, obvykle to není dobrý nápad, ale pokud vyhodnotíš, že v dané situaci se to vyplatí, tak si tím můžeš kód zjednodušit. Uznávám, že u IoC/DI je to horké téma a lze toho snadno zneužít, což je špatně, ale když už to vypadá fakt krkolomně, někdy stojí za to princip porušit :-)
Proto bych i vysvětlování vzorů a principů popsal jako "přemýšlejte nad problémem a pochopte slabiny a silné stránky použitého řešení" spíše než "dodržte nutně všechny principy, i kdyby to v dané situaci bylo na hlavu".
Samozřejmě nelze se zamýšlet nad každým řádkem kódu hodinu, principy jsou fajn pro většinu situací, ale když to začne vypadat krkolomně, tak je někdy třeba nebát se je porušit a použít selský rozum.
Toť co jsem chtěl říct, dobrou noc. Díky za debatu, bylo to zajímavé pro mě, i když jsme se většinu doby nechápali :-)

 
Odpovědět 2.10.2017 23:38
Avatar
eaktivo
Člen
Avatar
eaktivo:3.10.2017 8:02

"neměli zabývat optimalizací kódu, dokud to není opravdu potřeba" - s tymto absolutne nesuhlasim. Optimalizaciou kodu sa netreba zaoberat mozno dovtedy, pokym nie je vsetko funkcne. Ked uz to je funkcne, potom treba robit optimalizaciu. Optimalizacia by sa mala robit vzdy !! Inak z toho vznikne "Windows" - miesto 50 MB to ma 15 GB. Dnes uz neoptimalizuje nik. Ked dokazali manici napisat windows na 8-bitovy pocitac, ktory mal 64 kB RAM, tak potom sucasny Windows nemoze mat viac ako 50 MB. :-) :-) :-) Problem je, ze dnes nik neoptimalizuje. Radsej si dokupi 16 GB RAM a o 3 GHz rychlejsi procesor. :-):-):-)

 
Odpovědět  -2 3.10.2017 8:02
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na eaktivo
David Čápka:3.10.2017 8:55

Čas programátora stojí minimálně 40k/měsíc, čas stroje nestojí skoro nic. Proto se optimalizace tak nehrotí. Programátoři téměř vždy v práci nestíhají dělat vůbec funkcionalitu, natož aby ji zbytečně optimalizovali, aby měla na 1 TB disku 15 MB místo 50 MB. K čemu by to bylo dobré? Buď můžeš dát lidem produkt s 10 funkcemi nebo produkt s 5 funkcemi, který zabírá méně na disku, ale jim je to jedno. Když budeš takhle přemýšlet, tak tě konkurence brzo zničí.

Odpovědět  +4 3.10.2017 8:55
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Avatar
eaktivo
Člen
Avatar
Odpovídá na David Čápka
eaktivo:3.10.2017 9:10

Veď to je ten problém, že nie je na nič čas. Spraví sa hardware a ovládače sa odflakajú - potom to tak aj funguje. Všetko sa robí rýchlo, na nič nie je čas a potom to tak aj vyzerá. Optimalizácia nie je len o mieste, ale aj o rýchlosti. Priklad dobrej optimalizácie je napríklad Unreal engine. Keď hrám hodinu hru v Unreal engine, tak na grafickej karte sa ani neroztočí ventilátor. Ked pozriem CryEngine, tak po 5 minutách už možem variť čaj na grafickej karte. Pritom výsledok je v podstate ten istý. Nie celkom, lebo ten unreal ide na 120 fps a ten CryEngine na 50 fps ledva. Tomu sa hovorí rozdiel v optimalizácii. Ďalšia vec je - kupím si hardware a za pol roka už nejdem zohnať ovládač - nie je čas. Len Apple má na to čas, aby upravil iOS pre každý hardware. Android ? Kúp si nový telefón, keď chceš nový Android. :-D Všetko sa tlači do GB a GHz. Som zvedaví, že dokedy. :-D

 
Odpovědět 3.10.2017 9:10
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na eaktivo
Luboš Běhounek Satik:3.10.2017 9:23

Čas jsou peníze a optimalizace SW může trvat klidně násobně víc času, než jeho napsání, přitom je klidně možný, že to zrychlíš jen o pár procent.

Kdo by chtěl zaplatit za SW 3x víc jen aby mu to ve výsledku běželo třeba jen o 20% rychlejc, čehož si ani nevšimneš, dokud to exaktně nezměříš?

Proto se u komerčních aplikací obvykle optimalizuje až ve chvíli, kdy něco běží znatelněji pomalu, než by asi mělo.

Odpovědět  +3 3.10.2017 9:23
https://www.facebook.com/peasantsandcastles/
Avatar
Odpovídá na eaktivo
Michal Štěpánek:3.10.2017 9:45

Trošku se mi zdá, že mícháš dohromady dva pojmy "optimalizace kódu" a "optimální psaní kódu". Podle mě jsou to dvě různé činnosti. Pod pojmem "optimalizace kódu" já rozumím takovou činnost, při které si sednu nad už hotový kód, nebo jeho část a začnu vymýšlet, co bych na něm mohl upravit nebo změnit, aby to fungovalo o trošku lépe. A to si myslím, že myslel David Čápka větou

neměli zabývat optimalizací kódu, dokud to není opravdu potřeba.

Odpovědět  +1 3.10.2017 9:45
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
eaktivo
Člen
Avatar
Odpovídá na Luboš Běhounek Satik
eaktivo:3.10.2017 9:54

Problém tohoto sveta je kvantita na úkor kvality. Každý chce rýchlo niečo spraviť a rýchlo zhrabnúť prachy - pritom cena produktu neodzrkadluje kvalitu. Nie je to len problém IT a programovania, ale všetkého. Apple je na prvom mieste v ziskoch. Možno si ľudia radsej priplatia za tú optimalizáciu a čas, ktorý nad ňou tí programátori strávia ako za rýchlo spravené dielo na ktorého opravy, update a upgrade nie je čas. Google vyhľadávač je celý postavený na optimalizácii, inak by nebol tam kde je. A oplatilo sa investovať do viac ľudí, do času, do vývoja, do optimalizácie. A pokračujú v tom ďalej....

 
Odpovědět  +1 3.10.2017 9:54
Avatar
eaktivo
Člen
Avatar
Odpovídá na Michal Štěpánek
eaktivo:3.10.2017 9:59

Dokončím kód a optimalizujem na rýchlosť a miesto.
Keď mam Microkontroler ktorý ma 2 kB pamäti a 1 Mhz, tak mi je každý bajt a každý Hz cenný. Keď máš 16 GB a 4 Ghz, tak sa to dá nagrcať hocijako a väčinou to pojde ok. Čím viac GB, tým sa to lepšie predáva.

 
Odpovědět 3.10.2017 9:59
Avatar
Marian Benčat
Redaktor
Avatar
Odpovídá na eaktivo
Marian Benčat:3.10.2017 10:19

"premature optimalizace" , víš co je asi, že? :-) NIKDY se neoptimalizuje a ani neoptimalizovalo v prvé řadě.. Ani ten demoscénař nepsal tu svoje demo na ZX hned na první dobrou. Máš vesměs 2 druhy softwaru:

  1. Standardní komerční software, který dělá 95% trhu a kde se neoptimalizuje vůbec, nebo až po dokončení funkcionality, kdy se detekují pomocí profileru hotspoty a ty se pak řeší.
  2. SW kde potřebuješ výkonu hodně a ten je na takové úrovni, že už na úrovni ani těch algoritmů toho tolik nevyřešíš, takže jdeš níže - začneš u datových struktur, takže si nepouštíš ani časový profiler, ale spíše CPU profiler a sleduješ CPU countery.. především pak práci s pamětí, branche prediction atp.. Na tomto základě pak především optimalizuješ uskladnění dat v paměti atp.

Ty změny jsou ale pak tak strašně moc markantní, že u tohoto SW se vyplatí skutečně už hned od začátku ho navrhovat tak, aby byl optimální a tady se už při vývoji optimalizuje, protože pak by to bylo později mnohem náročnější.


Z výše zmíněného jsem ti chtěl nenápadně nastínit, že dnešní technologie už jsou na takové úrovni a rychlosti, že to brzdí výkon není práce CPU, která se právě optimalizuje a optimalizovala na microcontrollery, ale I/O operace - tedy práce s pamětí.. A tu budeš řešit u komerčního SW až po dokončení funkcionalit, když tě to HODNĚ pálí.. a pak u zbylých 2% SW typu GPGPU výpočtů, náročných CPu výpočtů atp.

Odpovědět  +4 3.10.2017 10:19
Totalitní admini..
Avatar
eaktivo
Člen
Avatar
Odpovídá na Marian Benčat
eaktivo:3.10.2017 10:55

Stale mi vrta v hlave ta optimalizacia. Na Amige (7,14 Mhz, 1 MB RAM) som mal operacny system na troch 880 kB disketach a tento Windows ma 4 GB a po nainstalovani 15 GB. Viditelny rozdiel vidim len v rozliseni a pocte farieb. Kompresiu / dekopresiu medii a 3D robi dnes uz v podstate hardver, tak mi je ten rozdiel neprimerany. Podla mna by mal mat v dnesnej dobe tak 250 MB max. bez tych omalovanok (medii) co su nevyhnutne. Chyba tam optimalizacia ak aj v inych softveroch ako je Adobe, Autodesk, ...

 
Odpovědět 3.10.2017 10:55
Avatar
Luboš Běhounek Satik
Autoredaktor
Avatar
Odpovídá na eaktivo
Luboš Běhounek Satik:3.10.2017 11:16

Na Amige (7,14 Mhz, 1 MB RAM) som mal operacny system na troch 880 kB disketach a tento Windows ma 4 GB a po nainstalovani 15 GB. Viditelny rozdiel vidim len v rozliseni a pocte farieb. Kompresiu / dekopresiu medii a 3D robi dnes uz v podstate hardver, tak mi je ten rozdiel neprimerany. Podla mna by mal mat v dnesnej dobe tak 250 MB max. bez tych omalovanok (medii) co su nevyhnutne.

Jaka optimalizace podle tebe ve Win chybi? Problem s velikosti Win je ten, ze spousta DLL je tam ulozena ve vice verzich kvuli zpetny kompatibilite.

250MB? Jen samotny dllka v System32 maj u me pres 4 GB, jak tohle chces nacpat do 250 MB?

Ono kdyz si neuvedomujes, co vsechno ve Win je, tak se nedivim, ze ti prijdou velky - ono teda samozrejme velky jsou a zmensit by jeste urcite sly, ale nemysli se, ze i o to se vyvojari nesnazej :)

Odpovědět  +1 3.10.2017 11:16
https://www.facebook.com/peasantsandcastles/
Avatar
David Čápka
Tým ITnetwork
Avatar
Odpovídá na berykubik
David Čápka:3.10.2017 11:59

Souhlas, taky díky za diskuzi. K těm třídám mimo root, často ve složce "vendor", jsou často menší a i kdyby tam bylo hodně zanoření se závislostmi, rozdíl je v tom, že ty knihovny píšeš/používáš obvykle hned pro několik projektů. Typicky si tedy člověk postahuje hotové knihovny, napíše si jednu nebo 2 specifické. Tam máš pravdu, že závislosti předá ručně. Vše ostatní pak jede přes DI. U hodně projektů člověk ani žádný kód mimo root nepíše, prostě to jen poskládá. Když už bych psal nějakou knihovnu, tak bych to předal ručně, nějaké Singletony by mohly být špatně použité někým, kdo tu knihovnu nezná a vytáhne si nějakou instanci, kterou si vytáhnout neměl. Myslím, že jsme se tedy shodli :)

Odpovědět 3.10.2017 11:59
Jsem moc rád, že jsi na síti, a přeji ti top IT kariéru, ať jako zaměstnanec nebo podnikatel. Máš na to! :)
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 32 zpráv z 32.