日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用装饰者模式做有趣的事情

發布時間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用装饰者模式做有趣的事情 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是裝飾者模式

裝飾者模式是一種為函數或類增添特性的技術,它可以讓我們在不修改原來對象的基礎上,為其增添新的能力和行為。它本質上也是一個函數(在javascipt中,類也只是函數的語法糖)。

我們什么時候可以弄到它呢

我們來假設一個場景,一個自行車商店有幾種型號的自行車,現在商店允許用戶為每一種自行車提供一些額外的配件,比如前燈、尾燈、鈴鐺等。每選擇一種或幾種配件都會影響自行車的售價。

如果按照比較傳統的創建子類的方式,就等于我們目前有一個自行車基類,而我們要為每一種可能的選擇創建一個新的類。可是由于用戶可以選擇一種或者幾種任意的配件,這就導致最終可能會生產幾十上百個子類,這明顯是不科學的。然而,對這種情況,我們可以使用裝飾者模式來解決這個問題。

自行車的基類如下:

class Bicycle {// 其它方法wash () {}ride () {}getPrice() {return 200;} } 復制代碼

那么我們可以先創建一個裝飾者模式基類

class BicycleDecotator {constructor(bicycle) {this.bicycle = bicycle;}wash () {return this.bicycle.wash();}ride () {return this.bicycle.ride();}getPrice() {return this.bicycle.getPrice();} } 復制代碼

這個基類其實沒有做什么事情,它只是接受一個Bicycle實例,實現其對應的方法,并且將調用其方法返回而已。

有了這個基類之后,我們就可以根據我們的需求對原來的Bicycle類為所欲為了。比如我可以創建一個添加了前燈的裝飾器以及添加了尾燈的裝飾器:

class HeadLightDecorator extends BicycleDecorator {constructor(bicycle) {super(bicycle);}getPrice() {return this.bicycle.getPrice() + 20;} } class TailLightDecorator extends BicycleDecorator {constructor(bicycle) {super(bicycle);}getPrice() {return this.bicycle.getPrice() + 20;} } 復制代碼

那么,接下來我們就可以來對其自由組合了:

let bicycle = new Bicycle(); console.log(bicycle.getPrice()); // 200 bicycle = new HeadLightDecorator(bicycle); // 添加了前燈的自行車 console.log(bicycle.getPrice()); // 220 bicycle = new TailLightDecorator(bicycle); // 添加了前燈和尾燈的自行車 console.log(bicycle.getPrice()); // 240 復制代碼

這樣寫的好處是什么呢?假設說我們有10個配件,那么我們只需要寫10個配件裝飾器,然后就可以任意搭配成不同配件的自行車并計算價格。而如果是按照子類的實現方式的話,10個配件可能就需要有幾百個甚至上千個子類了。

從例子中我們可以看出裝飾者模式的適用場合:

  • 如果你需要為類增添特性或職責,可是從類派生子類的解決方法并不太現實的情況下,就應該使用裝飾者模式。
  • 在例子中,我們并沒有對原來的Bicycle基類進行修改,因此也不會對原有的代碼產生副作用。我們只是在原有的基礎上增添了一些功能。因此,如果想為對象增添特性又不想改變使用該對象的代碼的話,則可以采用裝飾者模式。
  • 裝飾者模式除了可以應用在類上之外,還可以應用在函數上(其實這就是高階函數)。比如,我們想測量函數的執行時間,那么我可以寫這么一個裝飾器:

    function func() {console.log('func'); } function timeProfileDecorator(func) {return function (...args) {const startTime = new Date();func.call(this, ...args);const elapserdTime = (new Date()).getTime() - startTime.getTime();console.log(`該函數消耗了${elapserdTime}ms`);} } const newFunc = timeProfileDecorator(func); console.log(newFunc()); 復制代碼

    做一些有趣的事情

    既然知道了裝飾者模式可以在不修改原來代碼的情況下為其增添一些新的功能,那么我們就可以來做一些有趣的事情。

    我們可以為一個類的方法提供性能分析的功能。

    class TimeProfileDecorator {constructor(component, keys) {this.component = component;this.timers = {};const self = this;for (let i in keys) {let key = keys[i];if (typeof component[key] === 'function') {this[key] = function(...args) {this.startTimer(key);// 解決this引用錯誤問題component[key].call(component, ...args);this.logTimer(key);}}}}startTimer(namespace) {this.timers[namespace] = new Date();}logTimer(namespace) {const elapserdTime = (new Date()).getTime() - this.timers[namespace].getTime();console.log(`該函數消耗了${elapserdTime}ms`);} } // example class Test {constructor() {this.name = 'cjg';this.age = 22;}sayName() {console.log(this.name);}sayAge() {console.log(this.age);} }let test1 = new Test(); test1 = new TimeProfileDecorator(test1, ['sayName', 'sayAge']); console.log(test1.sayName()); console.log(test1.sayAge()); 復制代碼

    對函數進行增強

  • 節流函數or防抖函數

    function throttle(func, delay) {const self = this;let tid;return function(...args) {if (tid) return;tid = setTimeout(() => {func.call(self, ...args);tid = null;}, delay);} }function debounce(func, delay) {const self = this;let tid;return function(...args) {if (tid) clearTimeout(tid);tid = setTimeout(() => {func.call(self, ...args);tid = null;}, delay);} } 復制代碼
  • 緩存函數返回值

    // 緩存函數結果,對于一些計算量比較大的函數效果比較明顯。 function memorize(func) {const cache = {};return function (...args) {const key = JSON.stringify(args);if (cache[key]) {console.log('緩存了');return cache[key];}const result = func.call(this, ...args);cache[key] = result;return result;}; }function fib(num) {return num < 2 ? num : fib(num - 1) + fib(num - 2); }const enhanceFib = memorize(fib); console.log(enhanceFib(40)); console.log(enhanceFib(40)); console.log(enhanceFib(40)); console.log(enhanceFib(40)); 復制代碼
  • 構造React高階組件,為組件增加額外的功能,比如為組件提供shallowCompare功能:

    import React from 'react'; const { Component } = react;const ShadowCompareDecorator = (Instance) => class extends Component {shouldComponentUpdate(nextProps, nextState) {return !shallowCompare(this.props, nextProps) ||!shallowCompare(this.state, nextState);}render() {return (<Instance {...this.props} />);} };export default ShadowCompareDecorator; 復制代碼

    當然,你如果用過react-redux的話,你肯定也用過connect。其實connect也是一種高階組件的方式。它通過裝飾者模式,從Provider的context里拿到全局的state,并且將其通過props的方式傳給原來的組件。

    總結

    使用裝飾者模式可以讓我們為原有的類和函數增添新的功能,并且不會修改原有的代碼或者改變其調用方式,因此不會對原有的系統帶來副作用。我們也不用擔心原來系統會因為它而失靈或者不兼容。就我個人而言,我覺得這是一種特別好用的設計模式。

    一個好消息就是,js的裝飾器已經加入了es7的草案里啦。它讓我們可以更加優雅的使用裝飾者模式,如果有興趣的可以添加下babel的plugins插件提前體驗下。阮一峰老師的這個教程也十分淺顯易懂。

    覺得幫助的麻煩點下贊哦。謝謝。

    本文地址在->本人博客地址, 歡迎給個 start 或 follow 參考文獻:

    Javascript設計模式

    總結

    以上是生活随笔為你收集整理的使用装饰者模式做有趣的事情的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 欧美一区二区日韩一区二区 | 日韩欧美少妇 | xx在线视频 | 欧美日韩亚洲国产一区 | 91亚洲国产成人精品一区二三 | 日本黄图 | 四虎久久久 | 久久影视一区二区 | 国产在线三区 | 色视频免费 | 开心激情亚洲 | 国产成人高清在线 | 自拍视频一区二区 | 亚洲国产欧美日韩在线 | 蜜臀av在线免费观看 | 成人黄色片免费看 | 青青草.com| av在线免费播放网站 | 看国产一级片 | youjizzcom日本 | 亚洲a级在线观看 | 三级免费网址 | www.中文字幕av | 日日夜夜免费 | 日本一区二区三区久久 | 懂色一区二区 | 我要看免费的毛片 | 中文久久久 | 亚洲国产精品成人综合久久久 | 国产女人18毛片水真多 | 中文字幕1区2区 | 亚洲欧美日本在线观看 | av一卡| 亚洲精品一区二区在线 | 一本一道精品欧美中文字幕 | 91丨九色丨海角社区 | 精品久久久国产 | 国产www性 | av福利在线| 极品蜜桃臀肥臀-x88av | 一级特黄毛片 | 久久婷婷一区 | 别揉我奶头一区二区三区 | 亚洲制服丝袜av | 亚洲少妇30p | 欧美在线一区二区三区四区 | 在线免费看黄色片 | 国产在线观看免费高清 | 黄频在线免费观看 | 日韩精品电影网 | av黄色国产| 成人午夜在线 | 中国毛片在线 | 欧美大片xxxx | 99久久影院| 国产香蕉视频在线观看 | 国产精品无码久久av | 国产中文字幕在线观看 | 午夜在线一区二区三区 | 激情综合五月天 | 波多野结衣在线观看一区二区三区 | 欧美色图狠狠干 | 一本色道久久综合亚洲 | 69视频一区二区三区 | 国产成人无码一区二区三区在线 | 中文字幕亚洲色图 | 韩国一区二区在线播放 | 91免费视频免费版 | 精品视频网站 | 一级黄色片免费观看 | 日韩欧美三级 | 国产裸体网站 | 国产真实交换夫妇视频 | 国产免费视频一区二区三区 | 欧美在线不卡 | 在线观看日本网站 | 中文无码一区二区三区在线观看 | wwwxxx日本人 | 催眠调教后宫乱淫校园 | 国产欧美一区二区三区在线老狼 | 中文视频一区二区 | 国产乱人视频 | 欧美a v在线播放 | 看av的网址 | 欧美色图影院 | 日韩精品在线电影 | 美女屁股眼视频网站 | 在线观看视频国产 | 天天干天天操天天干 | 日本熟妇人妻中出 | 少妇太爽了在线观看 | 国产人妻人伦精品1国产盗摄 | 极品少妇av| 又大又粗又爽18禁免费看 | 国产91久久婷婷一区二区 | 超碰狠狠干 | 久久久久九九九 | 日韩图色 | 精品一区二区视频在线观看 |