真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

JavaScript中裝飾者模式與AOP的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)JavaScript中裝飾者模式與AOP的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

公司主營(yíng)業(yè)務(wù):網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)推出廣德免費(fèi)做網(wǎng)站回饋大家。

什么是裝飾者模式

當(dāng)我們拍了一張照片準(zhǔn)備發(fā)朋友圈時(shí),許多小伙伴會(huì)選擇給照片加上濾鏡。同一張照片、不同的濾鏡組合起來就會(huì)有不同的體驗(yàn)。這里實(shí)際上就應(yīng)用了裝飾者模式:是通過濾鏡裝飾了照片。在不改變對(duì)象(照片)的情況下動(dòng)態(tài)的為其添加功能(濾鏡)。

需要注意的是:由于 JavaScript 語言動(dòng)態(tài)的特性,我們很容易就能改變某個(gè)對(duì)象(JavaScript 中函數(shù)是一等公民)。但是我們要盡量避免直接改寫某個(gè)函數(shù),這會(huì)導(dǎo)致代碼的可維護(hù)性、可擴(kuò)展性變差,甚至?xí)廴酒渌麡I(yè)務(wù)。

什么是 AOP

想必大家對(duì)"餐前洗手、飯后漱口"都不陌生。這句標(biāo)語其實(shí)就是 AOP 在生活中的例子:吃飯這個(gè)動(dòng)作相當(dāng)于切點(diǎn),我們可以在這個(gè)切點(diǎn)前、后插入其它如洗手等動(dòng)作。

AOP(Aspect-Oriented Programming):面向切面編程,是對(duì) OOP 的補(bǔ)充。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,也可以隔離業(yè)務(wù)無關(guān)的功能比如日志上報(bào)、異常處理等,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高業(yè)務(wù)無關(guān)的功能的復(fù)用性,也就提高了開發(fā)的效率。

在 JavaScript 中,我們可以通過裝飾者模式來實(shí)現(xiàn) AOP,但是兩者并不是一個(gè)維度的概念。 AOP 是一種編程范式,而裝飾者是一種設(shè)計(jì)模式。

ES3 下裝飾者的實(shí)現(xiàn)

了解了裝飾者模式和 AOP 的概念之后,我們寫一段能夠兼容 ES3 的代碼來實(shí)現(xiàn)裝飾者模式:

// 原函數(shù)
var takePhoto =function(){
console.log('拍照片');
}
// 定義 aop 函數(shù)
var after=function( fn, afterfn ){ 
return function(){
let res = fn.apply( this, arguments ); 
afterfn.apply( this, arguments );
return res;
}
}
// 裝飾函數(shù)
var addFilter=function(){
console.log('加濾鏡');
}
// 用裝飾函數(shù)裝飾原函數(shù)
takePhoto=after(takePhoto,addFilter);
takePhoto();

這樣我們就實(shí)現(xiàn)了抽離拍照與濾鏡邏輯,如果以后需要自動(dòng)上傳功能,也可以通過aop函數(shù)after來添加。

ES5 下裝飾者的實(shí)現(xiàn)

在 ES5 中引入了Object.defineProperty,我們可以更方便的給對(duì)象添加屬性:

let takePhoto = function () {
console.log('拍照片');
}
// 給 takePhoto 添加屬性 after
Object.defineProperty(takePhoto, 'after', {
writable: true,
value: function () {
console.log('加濾鏡');
},
});
// 給 takePhoto 添加屬性 before
Object.defineProperty(takePhoto, 'before', {
writable: true,
value: function () {
console.log('打開相機(jī)');
},
});
// 包裝方法
let aop = function (fn) {
return function () {
fn.before()
fn()
fn.after()
}
}
takePhoto = aop(takePhoto)
takePhoto()

基于原型鏈和類的裝飾者實(shí)現(xiàn)

我們知道,在 JavaScript 中,函數(shù)也好,類也好都有著自己的原型,通過原型鏈我們也能夠很方便的動(dòng)態(tài)擴(kuò)展,以下是基于原型鏈的寫法:

class Test {
takePhoto() {
console.log('拍照');
}
}
// after AOP
function after(target, action, fn) {
let old = target.prototype[action];
if (old) {
target.prototype[action] = function () {
let self = this;
fn.bind(self);
fn(handle);
}
}
}
// 用 AOP 函數(shù)修飾原函數(shù)
after(Test, 'takePhoto', () => {
console.log('添加濾鏡');
});
let t = new Test();
t.takePhoto();

使用 ES7 修飾器實(shí)現(xiàn)裝飾者

在 ES7 中引入了@decorator 修飾器的提案,參考阮一峰的文章。修飾器是一個(gè)函數(shù),用來修改類的行為。目前Babel轉(zhuǎn)碼器已經(jīng)支持。注意修飾器只能裝飾類或者類屬性、方法。三者的具體區(qū)別請(qǐng)參考 MDN Object.defineProperty ;而 TypeScript 的實(shí)現(xiàn)又有所不同:TypeScript Decorator。

接下來我們通過修飾器來實(shí)現(xiàn)對(duì)方法的裝飾:

function after(target, key, desc) {
const { value } = desc;
desc.value = function (...args) {
let res = value.apply(this, args);
console.log('加濾鏡')
return res;
}
return desc;
}
class Test{
@after
takePhoto(){
console.log('拍照')
}
}
let t = new Test()
t.takePhoto()

可以看到,使用修飾器的代碼非常簡(jiǎn)潔明了。

場(chǎng)景:性能上報(bào)

裝飾者模式可以應(yīng)用在很多場(chǎng)景,典型的場(chǎng)景是記錄某異步請(qǐng)求請(qǐng)求耗時(shí)的性能數(shù)據(jù)并上報(bào):

function report(target, key, desc) {
const { value } = desc;
desc.value = async function (...args) {
let start = Date.now();
let res = await value.apply(this, args);
let millis = Date.now()-start;
// 上報(bào)代碼
return res;
}
return desc;
}
class Test{
@report
getData(url){
// fetch 代碼
}
}
let t = new Test()
t.getData()

這樣使用@report修飾后的代碼就會(huì)上報(bào)請(qǐng)求所消耗的時(shí)間。擴(kuò)展或者修改report函數(shù)不會(huì)影響業(yè)務(wù)代碼,反之亦然。

場(chǎng)景:異常處理

我們可以對(duì)原有代碼進(jìn)行簡(jiǎn)單的異常處理,而無需侵入式的修改:

function handleError(target, key, desc) {
const { value } = desc;
desc.value = async function (...args) {
let res;
try{
res = await value.apply(this, args);
}catch(err){
// 異常處理
logger.error(err)
}
return res;
}
return desc;
}
class Test{
@handleError
getData(url){
// fetch 代碼
}
}
let t = new Test()
t.getData()

通過以上兩個(gè)示例我們可以看到,修飾器的定義很簡(jiǎn)單,功能卻非常強(qiáng)大。

關(guān)于“JavaScript中裝飾者模式與AOP的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


網(wǎng)站欄目:JavaScript中裝飾者模式與AOP的示例分析
當(dāng)前網(wǎng)址:http://weahome.cn/article/jjscih.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部