成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS設(shè)計模式--裝飾者模式

wmui / 3287人閱讀

摘要:當(dāng)接口比較多,裝飾器也比較多時,可以獨立抽取一個裝飾器父類,實現(xiàn)目標類的所有接口,再創(chuàng)建真正的裝飾器來繼承這個父類。四的實現(xiàn)方式提供了一種類似的注解的語法糖,來實現(xiàn)裝飾者模式。

歡迎關(guān)注我的公眾號睿Talk,獲取我最新的文章:

一、前言

所謂裝飾者模式,就是動態(tài)的給類或?qū)ο笤黾勇氊?zé)的設(shè)計模式。它能在不改變類或?qū)ο笞陨淼幕A(chǔ)上,在程序的運行期間動態(tài)的添加職責(zé)。這種設(shè)計模式非常符合敏捷開發(fā)的設(shè)計思想:先提煉出產(chǎn)品的MVP(Minimum Viable Product,最小可用產(chǎn)品),再通過快速迭代的方式添加功能。

二、傳統(tǒng)面向?qū)ο笳Z言的實現(xiàn)方式
var Car = function() {}
Car.prototype.drive = function() {
    console.log("乞丐版");
}

var AutopilotDecorator = function(car) {
    this.car = car;
}
AutopilotDecorator.prototype.drive = function() {
    this.car.drive();
    console.log("啟動自動駕駛模式");
}

var car = new Car();
car = new AutopilotDecorator(car);
car.drive();    //乞丐版;啟動自動駕駛模式;

這種方式的實現(xiàn)要點是裝飾器類要維護目標對象的一個引用,同時要實現(xiàn)目標類的所有接口(這個例子里的drive方法,如果還有其它方法,比如brake,AutopilotDecorator也要實現(xiàn))。調(diào)用方法時,先執(zhí)行目標對象原有的方法,再執(zhí)行自行添加的特性。

當(dāng)接口比較多,裝飾器也比較多時,可以獨立抽取一個裝飾器父類,實現(xiàn)目標類的所有接口,再創(chuàng)建真正的裝飾器來繼承這個父類。

var Car = function() {}
Car.prototype.drive = function() {
    console.log("乞丐版");
}
/* 多了一個剎車方法 */
Car.prototype.brake = function() {
    console.log("剎車");
}

/* 實現(xiàn)所有接口的裝飾器父類 */
var CarDecorator = function(car) {
    this.car = car;
}
CarDecorator.prototype = {
    drive: function() {
        this.car.drive();
    },
    brake: function() {
        this.car.brake();
    }
}

/* 真正的裝飾器 */
var AutopilotDecorator = function(car) {
    CarDecorator.call(this, car);
}
AutopilotDecorator.prototype = new CarDecorator();
AutopilotDecorator.prototype.drive = function() {
    this.car.drive();
    console.log("啟動自動駕駛模式");
}

/* 真正的裝飾器 */
var HybridDecorator = function(car) {
    CarDecorator.call(this, car);
}
HybridDecorator.prototype = new CarDecorator();
HybridDecorator.prototype.brake = function() {
    this.car.brake();
    console.log("啟動充電模式");
}

var car = new Car();
car = new AutopilotDecorator(car);
car = new HybridDecorator(car);
car.drive();    //乞丐版;啟動自動駕駛模式;
car.brake();    //剎車;啟動充電模式;
三、JS基于對象的實現(xiàn)方式
var car = {
    drive: function() {
        console.log("乞丐版");
    }
}

var driveBasic = car.drive;

var autopilotDecorator = function() {
    console.log("啟動自動駕駛模式");
}

var carToDecorate = Object.create(car);

carToDecorate.drive = function() {
    driveBasic();
    autopilotDecorator();
}

carToDecorate.drive();    //乞丐版;啟動自動駕駛模式;

這種實現(xiàn)方式完全是基于JS自身的語言特點做考量。定義類的目的是實現(xiàn)代碼的封裝和復(fù)用,而JS這門語言是沒有類的概念的。它只有2種數(shù)據(jù)類型:基本類型和對象類型。實現(xiàn)邏輯的封裝和代碼的重用只需要通過對象來組織代碼,然后利用原生提供的克隆機制(Object.create)來達到目的。

從代碼的角度看,如果想擴展drive方法,只需要用一個變量來保存原函數(shù)的引用,然后再重寫drive方法就可以了。在重寫的方法里面,只要記得調(diào)用方法原有的行為就行。

另外,我們可以通過以下的工具函數(shù),達到裝飾函數(shù)的目的:

Function.prototype.after = function(afterfn) {
    var _self = this;
    return function() {
        var ret = _self.apply(this, arguments);
        afterfn.apply(this, arguments);
        return ret;
    }
}

var car = {
    drive: function() {
        console.log("乞丐版");
    }
}

var autopilotDecorator = function() {
    console.log("啟動自動駕駛模式");
}

var carToDecorate = Object.create(car);

carToDecorate.drive = car.drive.after(autopilotDecorator);

carToDecorate.drive();    //乞丐版;啟動自動駕駛模式;

通過在Function的原型鏈上定義after函數(shù),給所有的函數(shù)都賦予了被擴展的功能,當(dāng)然也可以根據(jù)需要定義一個before的函數(shù),在函數(shù)執(zhí)行前去做一些操作。這種實現(xiàn)方式借鑒了AOP(Aspect Oriented Programming,面向切面編程)的思想。

四、ES7的實現(xiàn)方式

ES7提供了一種類似的Java注解的語法糖decorator,來實現(xiàn)裝飾者模式。使用起來非常簡潔:

function autopilotDecorator(target, key, descriptor) {
    const method = descriptor.value;
    
    descriptor.value = () => {
        method.apply(target);
        console.log("啟動自動駕駛模式");
    }
    
    return descriptor;
}

class Car {
    @autopilotDecorator
    drive() {
        console.log("乞丐版");
    }
}

let car = new Car();
car.drive();    //乞丐版;啟動自動駕駛模式;

decorator的實現(xiàn)依賴于ES5的Object.defineProperty方法。defineProperty所做的事情是為一個對象增加新的屬性,或者更改某個已存在的屬性。調(diào)用方式是Object.defineProperty(obj, prop, descriptor)。

var o = {}; // 創(chuàng)建一個新對象

// 在對象中添加一個屬性
Object.defineProperty(o, "name", {
  value : "Dickens",
  writable : true,
  enumerable : true,
  configurable : true
});

// 在對象中添加一個方法
Object.defineProperty(o, "sayHello", {
  value : function() {
        console.log("Hello, my name is: ", this.name)
  },
  writable : true,
  enumerable : true,
  configurable : true
});

o.sayHello()    //Hello, my name is:  Dickens

decorator的參數(shù)跟defineProperty是完全一樣的,含義也類似,通過修改descripter,就能達到擴展功能的目的。

五、總結(jié)

本文介紹了裝飾者模式的基本概念,并通過不同的實現(xiàn)方式來介紹使用方法。對于不同的使用方法,也作了比較透徹的解釋,讓大家不但知其然,還知其所以然。

裝飾者模式是一種十分常用且功能強大的模式,利用ES7的語法糖,我們能用非常簡潔的方式來表達裝飾的意圖,推薦大家在實際項目中用起來。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93344.html

相關(guān)文章

  • TS下的裝飾模式(Decorator)

    摘要:裝飾者模式裝飾者模式就是動態(tài)的給類或?qū)ο笤黾庸δ艿脑O(shè)計模式。下的實現(xiàn)里的裝飾器目前處在建議征集的第二階段,不被瀏覽器所支持,如果想要提前使用這個新特性就需要,等工具進行轉(zhuǎn)譯。這里介紹下的用法。 1.1、裝飾者模式 裝飾者模式就是動態(tài)的給類或?qū)ο笤黾庸δ艿脑O(shè)計模式。在程序運行時動態(tài)的給一個具備基礎(chǔ)功能的類或?qū)ο筇砑有碌墓δ?,并且不會改變會破壞基礎(chǔ)類和對象的功能。先提煉出產(chǎn)品的最小可用產(chǎn)品...

    SolomonXie 評論0 收藏0
  • javascript設(shè)計模式 --- 裝飾模式

    摘要:設(shè)計模式裝飾者模式何為裝飾者,意思就是,在不影響對象主功能的情況下,再添加一些額外的功能,使對象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。 javascript設(shè)計模式 --- 裝飾者模式 何為裝飾者,意思就是,在不影響對象主功能的情況下,再添加一些額外的功能,使對象具備更多的功能。與繼承相比,裝飾者是一種更靈活輕便的做法。下面我們看看javascript里裝飾者模式 ...

    kumfo 評論0 收藏0
  • 學(xué)學(xué)AOP之裝飾模式

    摘要:但是,這樣做的后果就是,我們會不斷的改變本體,就像把鳳姐送去做整形手術(shù)一樣。在中,我們叫做引用裝飾。所以,這里引入的裝飾模式裝飾親切,熟悉,完美。實例講解裝飾上面那個例子,只能算是裝飾模式的一個不起眼的角落。 裝飾者,英文名叫decorator. 所謂的裝飾,從字面可以很容易的理解出,就是給 土肥圓,化個妝,華麗的轉(zhuǎn)身為白富美,但本體還是土肥圓。 說人話.咳咳~ 在js里面一切都是對...

    nihao 評論0 收藏0
  • 裝飾模式能做什么?

    摘要:自行車的基類如下其它方法那么我們可以先創(chuàng)建一個裝飾者模式基類這個基類其實沒有做什么事情,它只是接受一個實例,實現(xiàn)其對應(yīng)的方法,并且將調(diào)用其方法返回而已。 showImg(https://segmentfault.com/img/bVbs3pt?w=650&h=651); 什么是裝飾者模式 裝飾者模式是一種為函數(shù)或類增添特性的技術(shù),它可以讓我們在不修改原來對象的基礎(chǔ)上,為其增添新的能力和...

    Ilikewhite 評論0 收藏0
  • ES7-Decorator-裝飾模式

    摘要:裝飾者要實現(xiàn)這些相同的方法繼承自裝飾器對象創(chuàng)建具體的裝飾器,也是接收作對參數(shù)接下來我們要為每一個功能創(chuàng)建一個裝飾者對象,重寫父級方法,添加我們想要的功能。 裝飾模式 僅僅包裝現(xiàn)有的模塊,使之 更加華麗 ,并不會影響原有接口的功能 —— 好比你給手機添加一個外殼罷了,并不影響手機原有的通話、充電等功能; 使用 ES7 的 decorator ES7 中增加了一個 decorator 屬性...

    zhangxiangliang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<