javascript裝飾器模式,javascript裝飾模式

來源:互聯網
上載者:User

javascript裝飾器模式,javascript裝飾模式

眾所周知裝飾器模式用於給對象在運行期間動態增加某個功能,職責等。相較通過繼承的方式來擴充對象的功能,裝飾器顯得更加靈活,首先,我們可以動態給對象選定某個裝飾器,而不用hardcore繼承對象來實現某個功能點。其次:繼承的方式可能會導致子類繁多,僅僅為了增加某一個單一的功能點,顯得有些多餘了。

裝飾器經典實現

首先來看看傳統的decorator的實現吧!假設現有一類叫Person 的對象,該對象有個speak 方法。開始的時候Person 的對象只會說中文,現在我要讓他說英文,那麼可以這麼做:

var Person = function(name) {    this.name = name;};Person.prototype.speak = function() {    console.log('你好!');};var SpeakEnglish = function(person) {    this.person = person;       };SpeakEnglish.prototype.speak = function() {    this.speak();    console.log('hello!');};var SpeakJapanese = function(person) {    this.person = person;       };SpeakJapanese.prototype.speak = function() {    this.speak();    console.log('こんにちは!');};var lufy = new Person('lufy');var engLufy = new SpeakEnglish(lufy);var japanLufy = new SpeakJapanese(engLufy);japanLufy.speak();

通過封裝對象的方式給原對象增加新的功能,而不會影響原對象的同類對象。通過上面的方式路飛現在可以說3個國家的語言了。

javascript裝飾函數

對於javascript這類支援函數式編程的語言,我們要裝飾對象的某個方法其實也可以更加簡便,譬如說,通常我們寫前端頁面處理的時候需要監聽視窗的onload 事件,但是同樣一個onload 需要被多個地方監聽,可以這麼做:

var attachOnloadHandle = function(doit) {    if(typeof window.onload !== 'function') {        window.onload = doit;    }    else {        var func = window.onload;        window.onload = function() {            func();            doit();        };    }};

函數實現比較簡單,但也算實用吧!

裝飾器模式與AOP

AOP是面向切面編程的簡寫。其語意為把一些與核心業務模組無關的功能剝離出來,把整個系統劃分為更小的粒度。在完成這些子模組的設計編碼後再逐步封裝起來完成更大的功能。

javascript動態裝飾函數

通過前面的例子我們看到所謂裝飾無非是在執行某個功能之前執行一些前置或後置處理,提供兩個更加通用的介面:

Function.prototype.before = function(beforfunc) {    var self = this;    return function() {        beforfunc.apply(this, arguments);        self.apply(this, arguments);    };};Function.prototype.after = function(afterfunc) {    var self = this;    return function() {        self.apply(this, arguments);        afterfunc.apply(this, arguments);    };};

試一試:

var func = function() {    console.log('hello');   };func.before(function() {    console.log('你好');}).after(function() {    console.log('こんにちは!');});

考慮到安全方面的因素,我們在給伺服器發送一些請求的時候都需要帶上accessToken 有些操作不需要帶這個參數,通過AOP函數封裝我們可以這樣來做:

var getToken = function(cb) {    //...   };var preRequest = function(doit, params) {    var self = this;    getToken(function(err, token) {        if(err) {            //xxx            return;        }        self.token = token;        doit.apply(self, params);    });};var make = function(host, name, func) {    host[name] = function() {        this.preRequest(this['_' + name], arguments);    };    host['_' + name] = func;};//擷取卡券make(exports, 'getCard', function(cardId, cb) {    var url = 'http://www.wechat.com/xxxx' + this.token;    //...});

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.