JavaScript design patternek
A design patternek, vagyis magyarul a tervezési minták olyan építőkockák, melyek a gyakran előforduló, tipikus problémákra kínálnak jól működő, egységes, kalapból előhúzható megoldásokat. A feladatok mögött fel lehet fedezni mintázatokat, melyeket végül mindig ugyanúgy lehet a legjobban megoldani - ezen megoldások gyűjtőnevéről beszélünk. A bejegyzésben pár JavaScript tervezési mintáról írok, illetve adok egy pár linket is a témában.
Ha valaki általában kíváncsi a design patternekre, meg hogy honnan jött a fogalom, ajánlom neki ezt a blogbejegyzést, ahol Parragh Szabolcs írt egy rövid, de érdekes összefoglalót a témáról. Szintén jó összefoglalót ad Addy Osmani, a JavaScript tervezési mintákról írt könyvében.
Rátérve a bejegyzésem témájára, két patternt szeretnék kiemelni, melyeket azért tartok fontosnak, mert a kód szervezettségünkön, főként ha nagyobb mennyiségű JavaScript kódot írunk, nagyon-nagyon sokat tudnak segíteni. Az egyik a Singleton, a másik pedig a Modul pattern. A Singleton egy olyan erőforrást jelent, melyből az alkalmazásunkban egy példányt tartunk fenn. A Modul az objektum orientált nyelvek class-ait valósítja meg, privát és publikus metódusokkal, tulajdonságokkal. Rengeteg más pattern van még, érdemes mindegyikben gyakorlatot szerezni, és megérteni, hogy hogyan működnek. Továbbiakra is kitérek még néhány mondat erejéig.
Singleton pattern
Ahogy tehát említettem, a Singleton pattern segítségével egy olyan erőforrást valósíthatunk meg, melyből csak egy példány létezik a kódunkban, szemben az osztályokkal, melyekből több példányt is létrehozhatunk. Ha JavaScriptben létrehozunk egy sima függvényt, vagy változót, abból is csak egy példány lesz, így felmerülthet a kérdés, hogy egy Singleton megvalósítás miben is különbözik ettől, miben nyújt többet. A szervezettség a válasz, egy Singleton több összefüggő, azonos célú függvényt, változót gyűjt össze, és csomagol egybe.
JavaScriptben sokféleképpen megvalósíthatjuk ezt a patternt, de a legegyszerűbb megoldás egy objektum deklarálása, mely felsorolja a metódusokat és a változókat:
var SingletonNeve = {
metodus1: function(p1, p2) {
return p1+p2;
},
metodus2: function(p1, p2) {
return SingletonNeve.tulajdonsag1 + ' ' + SingletonNeve.metodus1(p1, p2);
},
tulajdonsag1: "Hello, én vagyok a Singleton!",
tulajdonsag2: "Hello Weblabor!"
}
A kódból az is látható, hogy egy Singleton hogyan tud magára hivatkozni: a saját nevének megadásával. A Singelon.metodus2(1,3)
meghívásával a "Hello, én vagyok a Singleton! 4"
választ fogjuk kapni.
Modul pattern
A Modul pattern egy sokkal összetettebben működő minta. A hagyományos OO osztályok mintájára privát és publikus metódusokat, tulajdonságokat tud létrehozni, melyek a JavaScript new
kulcsszavával példányosíthatóak. Hatalmas trükkök ugyan nincsenek benne, de azért szerepet kapnak a closure-ök, illetve a new
operátor használata:
var ModulNeve = function(p1, p2){
// privát metódusok
function privat1(n){
return "a végső válasz: "+n;
}
// privát változók
var privat_valtozo1;
// konstruktor
privat_valtozo1 = p2 - p1 + 23;
// publikus metódusok, változók
return {
publikus1: function() {
return privat1(this.publikus_valtozo1 + privat_valtozo1);
},
publikus_valtozo1: 42
}
};
var peldany = new ModulNeve(4, 8);
peldany.publikus_valtozo1 = 15;
console.log(peldany.publikus1());
Nézzük mi történik. Új, new
operátorral példányosítható osztályt a JavaScriptben egy sima függvény deklarációval hozhatunk létre, ez lesz a konstruktorunk. A függvény által return
nel visszaadott objektum lesz az az objektum, amit visszaad a new
. Az itt deklarált metódusokat, változókat el lehet érni kívülről. A closure-ök szabályai szerint, a konstruktor függvényben deklarált függvények és változók láthatóak a publikus metódusokból, de kívülről nem hozzáférhetőek.
Ez a tervezési minta elég jól átlátható kódot jelent, és alapvetően teljesen jól is működik. Egyik problémája, hogy ha utólag dinamikusan kiegészítjük a modult egy új metódussal, az - értelemszerűen - nem fogja látni a privát metódusokat, változókat.
A modul patternnek vannak további változatai, illetve a komolyabb JavaScript keretrendszerek (pl. YUI, DŌJŌ), vagy célkönyvtárak különféle módokon kényelmi szolgáltatásokat nyújtanak a használatához, ezeknek érdemes utánaolvasni.
További patternek
A többi pattern közül nehezen tudok kiemelni párat, nem azért mert nem lennének fontosak, hanem mert ugyanannyira jól jön a legtöbb a mindennapi munkában. Ami talán fontosabb lehet a többinél, hogy nagyobb kódbázisnál mindenképp érdemes a Namespace patternt használni, sokszor jól jöhet az Observer pattern, de ezek eléggé ad-hoc válogatott példák voltak.
További olvasnivaló
A források talán az Essential JavaScript Design Patterns For Beginners könyv és a JavaScript pattern and antipattern collection oldal, de érdemes még megnézni ezt a Module patternről szóló blogbejegyzést, az O'Reilly által kiadott JavaScript patterns könyvet. Létezik egy ismertebb blog is a témában, mely a http://www.jspatterns.com/ címen érhető el.
■
Alternatíva a singleton definíciójára
függvény neve
Van valami oka, hogy a függvénynek is nevet adtál? Anonymous függvényekkel is menne:
Hibakeresés
én valahol azt olvastam, hogy
fügvényneve.arguments
, és a függvénydeklaráció helyett meg alkalmazzunk függvénykifejezést. Azt nem tudom, hogy melyiknek mi a hátránya éppen, vagy az előnye, én keverve használom ahogy éppen rövidebb vagy praktikusabb.Valahol?
függvényneve.arguments
pedig nem helyes megközelítés eleve, mivel már régóta depricated. Függvénykifejezésnek pedig nevet csak akkor érdemes adni, ha a függvényen belül hivatkozni fogsz a nevére.Ez a megoldás egy olyan
AMD és CommonJS
Akit érdekel itt talál róla írást: http://addyosmani.com/writing-modular-js/ és http://tagneto.blogspot.com/
Én egyébként require.js-t (AMD pattern) használok Backbonenal (Constructor, Observer patternt).
A singleton pattern lényege,
Futtasd le
Nem új
Igen mindkettőtök válasza
Pattern gyűjtemény
Hmm, vélemény?
Javaslatok a weblabor.hu
Ha sokan támogatják, és nem bonyolult megvalósítani, akkor lehet rá számítani.
A Modult kicsit feltúrbóznám
Ím az eredmény (nem életszerű példa, csak techdemo):
De tovább is lehetne vinni...
Words reserved for possible future use
public
,private
).A private-re szerintem nincs
(A Singleton-nál van egy kis
A Modul-nál mi szükség van a "new" kulcsszóra? (költői kérdés...) Persze díszítő szerepe lehet... A new mindig a konstruktor egy "példányát" adja vissza, kivétel ha megadunk a konstruktornak visszatérő értéket... Én jobb szeretem a prototípus alapú "modul" készítést, szerintem átláthatóbb, bár vannak hátrányai is.
Személyes kedvencem
üdv,
kisPocok
Örökzöld
Kis gondolkodnivaló
Do Design patterns in Object Oriented Programming signal systemic problems of the paradigm of OO?