js設(shè)計模式-適配器模式、裝飾器模式(2)

github所有關(guān)于設(shè)計模式的代碼:js學(xué)習(xí)設(shè)計模式記錄

1.適配器模式

使用場景:
舊接口與使用者不兼容,中間添加一個轉(zhuǎn)換接口轧苫。
當(dāng)他人已完成的代碼在格式上不滿足新需求時,用適配器模式改變疫蔓。
例子: 德國插座轉(zhuǎn)換為中國插座

class Adoptee{
    specificRequest(){
        return "德國插座"
    }
}
class Adapter {
    constructor(){
        this.adoptee=new Adoptee()
    }
    request(){
        let info=this.adoptee.specificRequest()
        return `${info}-轉(zhuǎn)換-中國插座`
    }
}
console.log(new Adapter().request())

2.裝飾器模式

使用場景: 舊的功能繼續(xù)沿用含懊,但是要在舊的功能上添加身冬、修飾一些部分
例子: 原Circle類可以畫一個圓,現(xiàn)要畫圓岔乔,并且給這個圓添加邊框

class Circle{
    draw(){
        console.log("畫一個圓")
    }
}
class Decorator{
    constructor(){
        this.circle=new Circle()
    }
    draw(){
        this.circle.draw()
        this.fillBorder()
    }
    fillBorder(){
        console.log("添加邊框")
    }
}
new Decorator().draw()//畫一個圓  添加邊框

3.es7裝飾器介紹

裝飾器語法可參考:es6-裝飾器 JS 裝飾器

類裝飾器

定義一個Demon的類酥筝,定義裝飾器decorator1,@decorator1寫在calss Demon1的前面
decorator1會獲取到參數(shù)target,也就是當(dāng)前的Demon1類重罪∮:撸可以在decorator1這個函數(shù)中對Demon1的屬性進行處理,如下在Demon1中添加一個靜態(tài)屬性decorator="i am decorator"

@decorator1
class Demon1{
}
function decorator1(target) {
    target.decorator="i am decorator"
}
console.log(Demon1.decorator)//i am decorator

裝飾器對類的行為的改變剿配,是代碼編譯時發(fā)生的搅幅,而不是在運行時。裝飾器的原理如下

@decorator
class A{}
decorator(target){}
//相當(dāng)于↓↓
class A{}
A=decorator(A)||A

帶參數(shù)的裝飾器

@decorator2("new decorator")
class Demon2{
}
function decorator2(newValue){
    return function (target) {
        target.decorator=newValue
    }
}
console.log(Demon2.decorator)//new decorator

@decorator2("new decorator")執(zhí)行decorator2傳參“new decorator”呼胚,并且在decorator2的內(nèi)部返回不進行傳參時定義的裝飾器函數(shù)茄唐。
decorator2嵌套兩層function,第一層用來傳參蝇更,第二層是普通的裝飾器函數(shù)

@decorator2("new decorator")
class Demon2{
}
function decorator2(newValue){
    return function (target) {
        target.decorator=newValue
    }
}
console.log(Demon2.decorator)//new decorator

常用裝飾器 :Mixin示例

Mixin相關(guān)知識點參考:Mixin

Mixin是JavaScript中用的最普遍的模式沪编,幾乎所有流行類庫都會有Mixin的實現(xiàn)。
Mixin是摻合年扩,混合蚁廓,糅合的意思,即可以就任意一個對象的全部或部分屬性拷貝到另一個對象上厨幻。
下面的例子中通過裝飾器mixin將別的對象的屬性相嵌、方法添加到Demon3中
assign知識點:ES6之Object.assign()詳解

function mixin(list){
    return function (target) {
        Object.assign(target.prototype,...list)
    }
}
const append1={
    getAppend1Name(){
        console.log("append1")
    }
}

const append2={
    getAppend2Name(){
        console.log("append2")
    }
}
@mixin([ append1, append2])
class Demon3{

}
let demon3=new Demon3()
demon3.getAppend1Name()//append1
demon3.getAppend2Name()//append2

裝飾方法

readOnly 裝飾器
裝飾器總共接收三個參數(shù)target,value,description在下面例子中target是Demon4,value是getName况脆,description是getName的屬性描述符
設(shè)置屬性描述符的writable為false饭宾,將getName屬性設(shè)置為只讀

function readOnly(target,value,description) {
    description.writable=false
}

class Demon4 {
    constructor(){
        this.name="demon4"
    }
    @readOnly
    getName(){
        return this.name;
    }
}
const demon4=new Demon4()
demon4.getName=function () {//報錯:Uncaught TypeError: Cannot assign to read only property 'getName' of object '#<Demon4>'
    console.log("change")
}

修改getName時會報錯


image.png

log日志打印裝飾器
以下日志打印裝飾器在執(zhí)行setName時打印出舊的name值與新的name值
通過description.value重寫setName方法,使在調(diào)用原來的getName之前先console.log

function  log(target,value,description) {
    const oldValue=description.value
    description.value=function (name) {
        console.log(`previous name:${this.name}  new name is:${name}`)
        oldValue.call(this,arguments)
    }
}

class Demon5{
    constructor(){
        this.name="demon5"
    }
    @log
    setName(name){
        this.name=name
    }
}
const demon5=new Demon5()
demon5.setName("DEMON5")//previous name:demon5  new name is:DEMON5

建議不要手寫裝飾器格了,使用現(xiàn)成的裝飾器庫core-decorators.js

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末看铆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子盛末,更是在濱河造成了極大的恐慌弹惦,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悄但,死亡現(xiàn)場離奇詭異肤频,居然都是意外死亡,警方通過查閱死者的電腦和手機算墨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進店門宵荒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事报咳∠姥叮” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵暑刃,是天一觀的道長厢漩。 經(jīng)常有香客問我,道長岩臣,這世上最難降的妖魔是什么溜嗜? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮架谎,結(jié)果婚禮上炸宵,老公的妹妹穿的比我還像新娘。我一直安慰自己谷扣,他們只是感情好土全,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著会涎,像睡著了一般裹匙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上末秃,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天概页,我揣著相機與錄音,去河邊找鬼练慕。 笑死惰匙,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贺待。 我是一名探鬼主播徽曲,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼零截,長吁一口氣:“原來是場噩夢啊……” “哼麸塞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起涧衙,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤哪工,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后弧哎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雁比,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年撤嫩,在試婚紗的時候發(fā)現(xiàn)自己被綠了偎捎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茴她,靈堂內(nèi)的尸體忽然破棺而出寻拂,到底是詐尸還是另有隱情,我是刑警寧澤丈牢,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布祭钉,位于F島的核電站,受9級特大地震影響己沛,放射性物質(zhì)發(fā)生泄漏慌核。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一申尼、第九天 我趴在偏房一處隱蔽的房頂上張望垮卓。 院中可真熱鬧,春花似錦晶姊、人聲如沸扒接。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钾怔。三九已至,卻和暖如春蒙挑,著一層夾襖步出監(jiān)牢的瞬間宗侦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工忆蚀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留矾利,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓馋袜,卻偏偏與公主長得像男旗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子欣鳖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348

推薦閱讀更多精彩內(nèi)容