使用javascript更精確試作decorator pattern
Wed, 13 Jun 2007 23:14:40 +0800我在前幾篇文章裡面試做decorator pattern(用javascript試作decorator),但是總覺得不滿意,所以再試著弄更清楚。
幾個不清楚的地方是,我沒有嚴格地按照GoF的方式做,因為原本只是想初步達到效果(利用constructor彈性地賦予職責),但是class的關係不太明顯,說是decorator pattern有一點勉強,所以這一次再加強一下。
大致想做到幾點要求:
- decorator與被裝飾的對象,繼承同一個上層類別(觀念是這樣啦,但是用javascript實作其實感覺......類別關係不那麼強,沒辦法,先求有)
- 同樣用constructor可以動態賦予更多裝飾效果(職責)
程式很簡單,有一個最頂層的function叫做man,youngman跟decorator直接繼承man,singer跟conductor繼承decorator。youngman的shout方法會印出"I'm a young man"訊息,使用singer及conductor時則會為youngman加上"I'm a singer too."以及"I'm a conductor too."訊息。
function man () { this.shout = function () { } } function youngman () { this._init = man; this._init(); this._msg = "I'm a young man."; this.shout = function () { alert(this._msg); } } youngman.prototype = new man; function decorator (obj) { this._init = man; this._init(); this._obj = obj; this.shout = function () { } } decorator.prototype = new man; function singer (obj) { this._init = decorator; this._init(obj); this._msg = " I'm a singer too."; this.shout = function () { this._obj._msg += this._msg; this._obj.shout(); } } singer.prototype = new decorator; function conductor (obj) { this._init = decorator; this._init(obj); this._msg = " I'm a conductor too."; this.shout = function () { this._obj._msg += this._msg; this._obj.shout(); } } conductor.prototype = new decorator;
測試了一下:
var tmp1=new youngman(); tmp1.shout(); //印出"I'm a young man." var tmp2=new singer(new youngman()); tmp2.shout(); //印出"I'm a young man. I'm a singer too." var tmp3=new conductor(new youngman()); tmp3.shout(); //印出"I'm a young man. I'm a conductor too." var tmp4=new conductor(new singer(new youngman())); tmp4.shout(); //印出"I'm a young man. I'm a singer too. I'm a conductor too."
大概就是這樣了吧?希望沒大錯。
今天又看到一個有趣的想法,就是用類似的方式來做AOP,有空再來研究看看。(可以參考這篇blog文章:The Decorator Pattern for JavaScript)