JavaScript je ZLO 2.0

nenávistné poznámky vzteklého kodéra

Nad dopisy čtenářů

Několik zájemců mě požádalo abych trochu více objasnil co je to lib a k čemu slouží. Než tedy budu pokračovat v popisu práce s událostmi, pokusím se zodpovědět jejich otázky.
lib byla původně sada pomocných JS knihoven, která postupem času přerostla v provázaný framework.

Původní cíle a zásady se kterými knihovna vznikala by se daly shrnout do těchto bodů:

  • žádný programový kód by se neměl opakovat (DRY)
  • programový kód by měl být co nejjednodušší (KISS)
  • vyloučit nebo aspoň minimalizovat riziko kolizí, např. s jinými JS frameworky
  • nikdy nepsat Javascript přímo do HTML kódu (”unobtrusive JS”)
  • zakrýt rozdíly mezi browsery
  • nepoužívat “objektové” rysy JavaScriptu

Z těchto zásad vyplývají jak zjevné tak i méně zjevné rysy těchto knihoven:

Žádný programový kód by se neměl opakovat (DRY)

Tato zásada je už sama o sobě často motivací pro používání knihovních funkcí. Celý framework je rozdělen do tematicky zaměřených knihoven (např. lib.array - práce s poli, lib.evt - práce s událostmi, lib.ajax - asynchronní volání serveru) které mohou v případě potřeby být ve vztahu závislosti. Například knihovna lib.evt vyžaduje ke své práci knihovnu lib.array neboť pracuje s poli. Závislosti jsou vždy uvedeny v záhlaví souboru .js.
Některé často používané knihovny existují v “kompaktní” verzi, která má v jediném souboru zahrnuty i funkce z jiných knihoven, které ke svému běhu vyžaduje. Takovýto soubor má příponu .compact.js (např. evt.compact.js) a stačí ho připojit ke stránce, není třeba řešit jakékoli závislosti.

Programový kód by měl být co nejjednodušší (KISS)

Jednoduchost je velmi důležitá protože umožňuje údržbu a používání frameworku i málo zkušeným kodérům.
Co se týče API, tam je to jasné - je nutné používat krátké, výstižné názvy jmenných prostorů, funkcí i argumentů. Tam kde je třeba volit mezi stručností a srozumitelností volit vždy srozumitelnost.
I při implementaci jednotlivých funkcí je třeba dodržovat tento princip. Používat co nejjednodušší konstrukce. Kde to jde, vyvarovat se callbacků, closures, regulárních výrazů, ternárních operátorů a dalších nepřehledných konstrukcí. Přísně dodržovat syntaktické konvence.
Nepoužívat maďarskou notaci, pokud je vhodné uvést v identifikátoru jeho typ, potom ho uvést na konci identifikátoru. Vyvarovat se podobných identifikátorů (např. getElementsByClass a getElementByClass).
Pokud to jde, funkce by neměla být delší než 40 řádků (1 obrazovka). Kód by měl být takový, aby nepotřeboval komentář, ale přesto by se komentáři nemělo zbytečně šetřit.

Vyloučit nebo aspoň minimalizovat riziko kolizí, např. s jinými JS frameworky

V době vzniku základních knihoven frameworku lib ještě málokdo používal JS frameworky, nicméně příležitostí ke konfliktu bylo i tak mnoho. Framework by měl být schopen bez problémů operovat i ve velmi problematickém prostředí, dokáže spolupracovat s inline event handlery i event listenery, nemodifikuje žádné prototypy a přísně dodržuje jmenné prostory.

Nikdy nepsat Javascript přímo do HTML kódu (”unobtrusive JS”)

Framework nikdy nebyl používán pro “inline” skripty, operuje vždy jako nadstavba HTML stránky. Jednotlivé komponenty jsou často optimalizovány tak, aby je mohli snadno používat i programátoři nebo HTML kodéři, kteří nemají vůbec žádné znalosti JavaScriptu.
Dokonalé oddělení JS od HTML velmi usnadňuje tzv. funkční degradaci (důležité funkce musí fungovat i bez JS).

Zakrýt rozdíly mezi browsery

Framework je kompatibilní s browsery MSIE 6+, Mozilla/FF, Opera 7+ a Safari. V ostatních browserech obvykle také funguje ale je to bez záruky.
Uživatel knihoven se na úrovni API nemusí o nekompatibility browserů příliš starat, kód který funguje ve Firefoxu většinou funguje také v IE, Opeře a Safari.

Nepoužívat “objektové” rysy JavaScriptu

Javascript je velice silný jazyk založený na seznamech. Jeho “objektové” vlastnosti jsou však poněkud násilně přidané a nepříliš povedené. Protože pro většinu programátorů je prototypová dědičnost Javascriptu matoucí, rozhodl jsem se tyto mechanismy vůbec nepoužívat.
V překvapivě velkém počtu případů se lze bez dědičnosti snadno obejít a v takových případech to i doporučuji, protože objektový přístup je pro Javascript často zbytečně těžkopádný.
Pro případy, kdy je použití dědičnosti vysloveně vhodné, nabízí framework knihovnu lib.Class která simuluje klasickou dědičnost. S pomocí této knihovny je možné vytvářet jak třídy, tak i jejich instance bez použití mechanismů prototypové dědičnosti.
Tam kde je více možností syntaxe preferuji literálovou formu, neboť tu interpret obvykle dokáže rychleji zpracovat a bývá přehlednější na čtení.

Silné stránky (aneb co jinde nemají)

Každá knihovna má určité silné stránky kvůli kterým ji vůbec někdo používá. Za silné stránky frameworku lib považuji hlavně tyto:

  • práce s událostmi (lib.evt) - přesné řazení callbacků, snadnější odebírání event handlerů, do callback funkce se předávají praktičtější argumenty, možnost používat uživatelsky definované události
  • vytváření HTML elementů pomocí JSON šablon (lib.elm) - lze generovat i složité DOM struktury jediným příkazem podle JSON šablony, do šablony lze vkládat i existující elementy DOMu.
  • ukládání dat přímo do DOMu (lib.data) - framework zajišťuje bezpečné ukládání dat do elementů DOMu bez rizika kolize.
  • manipulace s polohou a rozměry elementů (lib.dhtml) - jednotný systém souřadnic, pozicování pomocí vektorů, zjišťování kolizí elementů, jednotná soustava z-indexů

Slabé stránky

Jsem si samozřejmě vědom i některých slabin frameworku lib. Za nejhorší považuji následující:

  • chyby - vzhledem k tomu že většinu funkcionality programuji sám, v méně používaných funkcích se občas skrývají chyby. Dokonce ani unit-testy některé věci neodhalí. Snažím se sice publikovat jen ty části frameworku které považuji za dobře odladěné, ale přesto mi občas něco proklouzne.
  • málo komponent GUI - ačkoli poslední dobou se situace lepší, komponent GUI mám stále ještě nedostatek. Jsou sice k dispozici věci jako validátor formulářů, modální okno, pulldown menu, suggest, tooltip, komponenta pro výběr času nebo rozbalovací strom, na druhou stranu chybí např. kalendář, DHTML editor či interaktivní tabulka. Tady by bylo pravděpodobně na místě použít YUI, nicméně nějaká integrace lib a YUI by se časem určitě hodila.
  • málo uživatelů, žádná komunita - vývoj tak postupuje poměrně pomalu kupředu a nemá příliš velkou zpětnou vazbu. Na druhou stranu zatím není nutné tak přísně dodržovat zpětnou kompatibilitu což se občas hodí.
  • nekompletní dokumentace - dokumentace sice existuje, nicméně je v ní hodně nepřesností a mnoho věcí chybí úplně. Navíc zatím není dostupná na webu.

Abych tyto problémy co nejjednodušším způsobem eliminoval, rozhodl jsem se publikovat tady na weblogu postupně jednotlivé knihovny frameworku. Podle ohlasu se potom rozhodnu jestli o ty věci vůbec někdo má zájem a zda má cenu se nějak výrazněji angažovat v popularizaci, publikaci dokumentace a případně i vytvoření nějaké vývojářské komunity.

Závěrem

Mám dojem že všeobecných teoretických plků bylo už dost. Pokud vás to nějak zajímá, podívejte se na články které o frameworku lib budu postupně publikovat, z těch snad pochopíte konkrétněji co se tady snažím popsat. A ptejte se, za to nic nedáte.



7 Komentářů k článku “Nad dopisy čtenářů”

  1. honza:

    ‘Nepoužívat “objektové” rysy JavaScriptu’ zní opravdu jako nenávisná poznámka vzteklého kodéra. A je to první věc, se kterou tady nesouhlasím.

    Objektovost nerovná se dědičnost. To, že v JS jsem nepoužil dědičnost, neznamená, že jsem neprogramoval neobjektově.


  2. richard:

    Od toho tady ten weblog je abych trousil vzteklé poznámky.
    Možná že jsem neměl psát objektové rysy, protože obzvláštní pifku mám na prototypovou dědičnost, ale mám i jiné námitky.
    -Prototypová dědičnost porušuje princip zapouzdření - když změním prototyp, změní se mi jeho potomci, i ti kteří už existují, to je docela hnus.
    -Kde to jde preferuji literálovou syntaxi - např. místo new String(”abc”) napíšu raději “abc”, míst new Object napíšu {} a místo new Array() píšu [] - kód se vykoná rychleji, je přehlednější a nemá to neblahé vedlejší efekty.
    -Modifikace vestavěných prototypů jako je String, Array nebo Objekt považuju z výše uvedených důvodů za barbarství. Člověk by měl programovat ohleduplně.
    -Obezličky jako je definice třídy pomocí konstruktorové funkce nebo vytvoření privátních vlastností objektu za pomoci closures se mi hnusí, není to ani elegantní ani přehledné.

    Javascript by se navíc bez svojí “objektové” části zcela bez problémů obešel. Celá tahle věc tam byla přidána z marketingových důvodů, aby se JS víc podobal Javě.


  3. MiSHAK:

    @honza Stále dokola… Objektové programování klidně, ale v JavaScriptu je prototypový model a ten je velmi vzdálené objektovému stylu. Vypadá podobně ale chová se jinak.


  4. podoh:

    Fajn stranka!!!! Hod si na nu google adsense. Mozes na tom fajn zarabat.
    Viac info na:

    http://letsmakesomemoneyonline.blogspot.com/


  5. richard:

    podoh: díky, ale adsense tu nemám záměrně, prozatím necítím potřebu na tomhle vydělávat.


  6. Hg:

    MiSHAK: Prototypový model je *plnohodnotnou* implementací objektového programování v té podobě, jakou přinesl Smalltalk 80. Třídy a spol. vůbec nejsou k naplnění definice OOP zapotřebí. Prototypové jazyky nejsou “velmi vzdálené objektovému stylu”, většina z nich má k objektovému programování naopak mnohem blíže než tzv. “moderní jazyky” typu Java.


  7. richard:

    MiSHAK: Omlouvám se že reaguju pozdě, jsem teď většinou v privátní síti bez přístupu na internet :-)

    Je možné že máš pravdu, Smalltalk 80 neznám. Pro mě ja ale důležité, že nedílnou součástí “objektového stylu”, jak ho chápu já a jak ho vnímá i naprostá většina programátorů které znám, je princip zapouzdření.
    Systém který nedodržuje princip zapouzdření (Encapsulation) vyžaduje zcela jiný programátorský přístup než např. Java.

    Hádat se o to co je “pravé objektové programování” je celkem k ničemu, takže já jen upřesním že to čemu říkám “objektové programování” má tyto rysy: information hiding, data abstraction, encapsulation, modularity, polymorphism, inheritance.


Přidejte komentář

For spam detection purposes, please copy the number 1917 to the field below:




Weblog "JavaScript je ZLO 2.0" pohání všelijak překopaný WordPress,
XHTML je skoro validní, celkem respektuje Dogma W4 ale ne úplně