亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

面向切面編程與裝飾器

lunaticf / 2496人閱讀

摘要:面向切面編程嗯,百度百科一下為的縮寫,意為面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。

面向切面編程

~~~~ 嗯,百度百科一下 ~~~~

AOP 為 Aspect Oriented Programming 的縮寫,意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP 是 OOP 的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),也是 Spring 框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用 AOP 可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。

作為前端的小萌理解為,就是將除主流程外的其他業(yè)務(wù)剝離出來(lái),然后從側(cè)面切入。對(duì)原功能無(wú)侵入式的修改。

話不多說(shuō),來(lái)個(gè)網(wǎng)上的經(jīng)典例子:

業(yè)務(wù)邏輯:

主業(yè)務(wù):修改數(shù)據(jù)庫(kù)

切入點(diǎn) 1:修改前打印日志

切入點(diǎn) 2:修改后打印日志

Function.prototype.before = function(beforeFunc) {
  let that = this
  return function() {
    beforeFunc.apply(this, arguments)
    return that.apply(this, arguments)
  }
}

Function.prototype.after = function(afterFunc) {
  let that = this
  return function() {
    let ret = that.apply(this, arguments)
    afterFunc.apply(this, arguments)
    return ret
  }
}

function updateDb() {
  console.log(`update db`)
}
function beforeUpdateDb() {
  console.log(`before update db`)
}
function afterUpdateDb() {
  console.log(`updated db`)
}
updateDb = updateDb.before(beforeUpdateDb).after(afterUpdateDb)
updateDb()

原理:其實(shí)就是將主業(yè)務(wù)updateDb包裹2次,返回一個(gè)新的方法。新方法會(huì)在原方法調(diào)用前后調(diào)用切入方法,避免在主方法上直接改動(dòng)。

這樣的可讀性和代碼維護(hù)性是不是很差,下面用裝飾器看看如何實(shí)現(xiàn)切面編程,

裝飾器 decorator

裝飾器是ES7現(xiàn)代游覽器并不兼容,需要babel轉(zhuǎn)譯,插件(babel-plugin-transform-decorators-legacy)

裝飾器只能作用于類本身、類的方法或?qū)傩浴⒃L問(wèn)操作符

修飾器“@”為標(biāo)識(shí)符

1 對(duì)類的裝飾
@create
class Apes {
 
}

// 修飾類本身
function create(className) {
  className.prototype.create = function() {
    console.log("制造工具")
  }
  return descriptor
}

let apes1 = new Apes()
apes1.create() 
// 制造工具

對(duì)類本身修飾:create(className)。裝飾器本質(zhì)就是編譯時(shí)執(zhí)行的函數(shù)。

要修飾子類,通過(guò)要className.prototype修飾子類。

2 對(duì)類的方法修飾
class Apes {
  @eatMore
  eat() {
    console.log("吃水果")
  }
}
// 修飾方法
function eatMore(className, propName, descriptor) {
  //console.log(descriptor)
  let value = descriptor.value
  descriptor.value = function() {
    console.log("吃土")
    value()
  }
  return descriptor
}

let apes1 = new Apes()
apes1.eat()

對(duì)類的方法裝飾 eatMore(className, propName, descriptor)

className - 被修飾的類
propName - 被修飾的屬性名
descriptor - 該屬性的描述對(duì)象

通過(guò)descriptor屬性描述符看出 依賴于ES5的Object.defineProperty

復(fù)習(xí)一下Object.defineProperty

value:屬性的值,默認(rèn)為undefined

writable:能否修改屬性的值,默認(rèn)值為true

enumerable:能否通過(guò)for-in循環(huán)返回屬性。默認(rèn)為ture

configurable:能否通過(guò)delete刪除屬性從而重新定義屬性,能否修改屬性的特性,能否把屬性修改為訪問(wèn)器屬性,默認(rèn)為true.

上面對(duì)類的方法修飾 實(shí)際是通過(guò) descriptor.value 拿到其方法,在進(jìn)行包裝返回

同時(shí)也可以直接修改descriptor上的其他屬性或者返回一個(gè)新的descriptor

3. 針對(duì) 訪問(wèn)操作符的裝飾
class test {
  //@nonenumerable
  get kidCount() {
    return 111
  }
}

function disWirte(target, name, descriptor) {
  descriptor.writable = false
  return descriptor
}
let p = new test()
console.log(p.kidCount)
p.kidCount = 222n descriptor;

// 拋出異常
// TypeError: Cannot set property kidCount of # which has only a getter
4. 修飾傳參
class Apes {
  @say("可以說(shuō)漢語(yǔ)了")
  say() {
    console.log("厵爨癵驫寶麣纞虋讟钃鸜麷鞻韽顟顠饙饙騳騱龗鱻爩麤")
  }
}

// 修飾方法并傳遞參數(shù)
function say(str) {
  return function(className, propName, descriptor) {
    descriptor.value = function() {
      console.log(str)
    }
    return descriptor
  }
}

通過(guò)柯里化的方式傳遞參數(shù)

應(yīng)用 1. 應(yīng)用在斐波那契數(shù)列計(jì)算中
const memory = () => {
  const cache = {} //緩存池
  return (target, name, descriptor) => {
    // 原方法
    const method = descriptor.value
    // 包裹原方法
    descriptor.value = function(key) {
      if (cache[key]) {
        return cache[key]
      }
      const ret = method.apply(target, [key])
      cache[key] = ret
      return ret
    }
    return descriptor
  }
}

let count = 0

class Test {
  @memory()
  fb(n) {
    count++
    if (n === 1) return 1
    if (n === 2) return 1
    return this.fb(n - 1) + this.fb(n - 2)
  }
}

const t = new Test()
console.log(t.fb(10))
console.log(count)
2. 訪問(wèn)操作符-set 上作類型檢查
class test {
  constructor() {
    this.a = 1
  }
  get a() {
    return this.a
  }
  @check("number")
  set a(v) {
    return v
  }
}

function check(type) {
  return function(target, prop, descriptor) {
    let v = descriptor.value
    return {
      enumerable: true,
      configurable: true,
      get: function() {
        return v
      },
      set: function(c) {
        var curType = typeCheck(c)
        if (curType !== type) {
          throw `${prop}必須為${type}類型`
        }
        v = c
      }
    }
  }
}

function typeCheck(c) {
  if (c === undefined) {
    return undefined
  }
  if (c === null) {
    return null
  }
  let type = typeof c
  if (type === "object") {
    return c.constructor == Array ? "array" : "object"
  }
  return type
}

let t = new test(11)
t.a = 2
console.log(t.a) // 2

t.a = []
console.log(t.a)
// throw a必須為number類型

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/106576.html

相關(guān)文章

  • 前端裝飾,AOP的使用

    摘要:中的裝飾在前端編程中,我們可以采用裝飾器,來(lái)實(shí)現(xiàn)編程。裝飾器使用我們先建立一個(gè)簡(jiǎn)單的類,這個(gè)類的作用,就是在執(zhí)行的時(shí)候,打印出。至此,一個(gè)簡(jiǎn)單的裝飾器范例已經(jīng)完成。 什么是裝飾器? 了解AOP 在學(xué)習(xí)js中的裝飾器之間,我們需要了解AOP(面向切面編程)編程思想。 AOP是一種可以通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)在不修改源代碼的情況下給程序動(dòng)態(tài)統(tǒng)一添加功能的一種技術(shù)。AOP實(shí)際是Go...

    lewinlee 評(píng)論0 收藏0
  • 面向復(fù)雜應(yīng)用,Node.js中的IoC容 -- Rockerjs/core

    摘要:項(xiàng)目地址項(xiàng)目主頁(yè)基于和注解的輕量級(jí)容器,提供了依賴注入面向切面編程及異常處理等功能??稍谌我夤こ讨幸耄且粋€(gè)框架無(wú)關(guān)的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫(kù)類等保持兼容。 Rockerjs Core 項(xiàng)目地址 項(xiàng)目主頁(yè) 基于 TypeScript 和注解的輕量級(jí)IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個(gè)框架無(wú)...

    jasperyang 評(píng)論0 收藏0
  • 面向復(fù)雜應(yīng)用,Node.js中的IoC容 -- Rockerjs/core

    摘要:項(xiàng)目地址項(xiàng)目主頁(yè)基于和注解的輕量級(jí)容器,提供了依賴注入面向切面編程及異常處理等功能??稍谌我夤こ讨幸耄且粋€(gè)框架無(wú)關(guān)的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫(kù)類等保持兼容。 Rockerjs Core 項(xiàng)目地址 項(xiàng)目主頁(yè) 基于 TypeScript 和注解的輕量級(jí)IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個(gè)框架無(wú)...

    Kosmos 評(píng)論0 收藏0
  • 5 分鐘即可掌握的 JavaScript 裝飾者模式 AOP

    摘要:下裝飾者的實(shí)現(xiàn)了解了裝飾者模式和的概念之后,我們寫一段能夠兼容的代碼來(lái)實(shí)現(xiàn)裝飾者模式原函數(shù)拍照片定義函數(shù)裝飾函數(shù)加濾鏡用裝飾函數(shù)裝飾原函數(shù)這樣我們就實(shí)現(xiàn)了抽離拍照與濾鏡邏輯,如果以后需要自動(dòng)上傳功能,也可以通過(guò)函數(shù)來(lái)添加。 showImg(https://segmentfault.com/img/bVbueyz?w=852&h=356); 什么是裝飾者模式 當(dāng)我們拍了一張照片準(zhǔn)備發(fā)朋友...

    chunquedong 評(píng)論0 收藏0
  • es6/es7之Decorator裝飾

    摘要:裝飾器顧名思義就是裝飾某種東西的方法,可以用來(lái)裝飾屬性變量函數(shù)類實(shí)例方法本質(zhì)上是個(gè)函數(shù)。以符開(kāi)頭,函數(shù)名稱自擬。愛(ài)吃蘋果裝飾器裝飾類愛(ài)吃蘋果結(jié)果是這個(gè)類本身就可以通過(guò)修改類的屬性增加屬性被裝飾的對(duì)象可以使用多個(gè)裝飾器。 @Decorator 裝飾器是es7的語(yǔ)法,這個(gè)方法對(duì)于面向切面編程有了更好的詮釋,在一些情境中可以使用,比如路人A的代碼實(shí)現(xiàn)了一需求,路人B希望用A的方法來(lái)實(shí)現(xiàn)一個(gè)新...

    yanest 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<