javascript設(shè)計模式

//構(gòu)造函數(shù)模式
// 用js構(gòu)造器創(chuàng)建一個對象后,
//新對象就會具有構(gòu)造器原型的所有屬性。
//通過這種方式,可以創(chuàng)建多個Car對象,并訪問相同的原型
function Car(name, year, miles) {
  this.name = name
  this.year = year
  this.miles = miles
}
Car.prototype.run = function () {
  return this.name + ' worked ' + this.miles + ' miles'
}

var Benz = new Car('s350', 2010, 20000)
var QQ = new Car('qq123', 2010, 300000)

console.log(Benz.run()) //s350 worked 20000 miles
console.log(QQ.run()) //qq123 worked 300000 miles



// 混合模式:將一批具有相同操作的對象組織成一個樹形結(jié)構(gòu),
//可以用一條命令在多個對象上激發(fā)復(fù)雜或者遞歸調(diào)用。
// 具有樹形結(jié)構(gòu)和相同操作的集合
//(如:圖片庫展現(xiàn),一個目錄下可能有目錄、
//圖片,這種情況,圖片就是葉子對象,
//目錄就是根對象或者子對象)
// 子節(jié)點(diǎn)個數(shù)或者操作實(shí)現(xiàn)不確定
//(如:表單驗(yàn)證,表單的數(shù)據(jù)項是不容易確定的,
//且有可能因用戶不同而表單區(qū)域不一樣)
function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.printName = function () {
  console.log(this.name)
}

function Student(name, age, score) {
  // 繼承 Person 的屬性
  Person.call(this, name, age)
  this.score = score
}

function create(prototype) {
  function F() {}
  F.prototype = prototype
  return new F()
}

// 讓Student的原型指向一個對象,
//該對象的原型指向了Person.prototype,
//通過這種方式繼承 Person 的方法
Student.prototype = create(Person.prototype)
Student.prototype.printAge = function () {
  console.log(this.age)
}
Student.prototype.sayScore = function () {
  console.log(this.score)
}
var student = new Student('admin', 22, 99)
student.printName() //  'admin'
console.log(student)


//模塊化
// 最初被定義為一種在傳統(tǒng)軟件工程中
//為類提供私有和公有封裝的方法。
// 方式: Module模式用于進(jìn)一步模擬類的概念,
// 好處: 能夠使一個單獨(dú)的對象擁有公有/私有方法和變量,
//從而屏蔽來自全局作用域的特殊部分
// 結(jié)果: 函數(shù)名與在頁面上
//其他腳本定義的函數(shù)沖突的可能性降低
var moudule = (function () {
  var counter = 0

  return {
    addCounter: function () {
      return counter = counter + 1
    },
    resetCounter: function () {
      console.log('value: ' + counter)
      counter = 0
    }
  }
})()

console.log(moudule)

moudule.addCounter()
moudule.resetCounter()



//工廠模式
// 為了解決多個類似對象聲明的問題,
//解決實(shí)例化對象產(chǎn)生大量重復(fù)的問題
function createObject(name, age) {
  var obj = new Object()
  obj.name = name
  obj.age = age
  obj.describe = function () {
    return this.name + ' ' + this.age
  }
  return obj
}

var obj1 = createObject('allen', 22)
var obj2 = createObject('bill', 23)

console.log(obj1.describe())
console.log(obj2.describe())



//單例模式
// 保證一個類僅有一個實(shí)例,并且提供一個訪問它的全局訪問點(diǎn)
var obj = function (name) {
  this.name = name
  this.instance = null
}

obj.prototype.getName = function () {
  console.log(this.name)
}

obj.getInstance = function () {
  if (!this.instance) {
    this.instance = new obj(name)
  }

  return this.instance
}

var a = obj.getInstance('about')
var b = obj.getInstance('instagram')
console.log(a === b)



//發(fā)布訂閱模式
// 這個模式用來作為中間人,
//一個把發(fā)布者和訂閱者架接在一起的代理。
//發(fā)布者是當(dāng)完成某些過程的時候觸發(fā)事件的對象,
//訂閱者是希望當(dāng)發(fā)布者發(fā)布的時候希望被通知的對象。

// 生活中有一個很好地例子,
//廣播電臺,
//人們會把頻道調(diào)到他們最喜歡的節(jié)目。
//廣播站不知道觀眾聽得是什么或者他們正在聽什么。
//他只需要發(fā)布他們的節(jié)目就可以啦。
//觀眾也不知道廣播站制作節(jié)目的過程。
//他們只要在他們最喜歡的節(jié)目運(yùn)行的時候
//把臺調(diào)到對應(yīng)的頻道或者告知朋友就行。

// 發(fā)布/訂閱者模式實(shí)現(xiàn)了松耦合:
//你可以讓發(fā)布者發(fā)布消息,
//訂閱者接受消息而不是尋找一種方式
//把兩個分離的系統(tǒng)連接在一起。
var makePubSub = function () {
  var callbacks = {},
    publish = function () {
      //將參數(shù)對象轉(zhuǎn)換為數(shù)組
var args = Array.prototype.slice.call(arguments, 0)

      //提取作為第一個事件
      var ev = args.shift()

      //Return 如果毀掉函數(shù)不包含
      //任何事件
      var list, i, l
      if (!callbacks[ev]) {
        return this
      }
      list = callbacks[ev]

      //調(diào)用回掉函數(shù),傳遞其余參數(shù)
      for (i = 0, l = list.lengthi < li++) {
        list[i].apply(this, args)
      }

      return this
    },
    subscribe = function (ev, callback) {
      //檢查是否注冊
      //如果不存在就創(chuàng)建一個數(shù)組
      if (!callbacks[ev]) {
        callbacks[ev] = []
      }
      callbacks[ev].push(callback)
      return this
    }

  return {
    pub: publish,
    sub: subscribe
  }
}

test = makePubSub()
test.sub("alert", function () {
  alert("hello")
})
test.pub("alert")


// 使用發(fā)布訂閱模式寫一個事件管理器,可以實(shí)現(xiàn)如下方式調(diào)用
// Event.on('change', function(val){
//     console.log('change...  now val is ' + val)  
// })
// Event.fire('change', '饑人谷')
// Event.off('changer')


var EventCenter = (function () {
  var events = {}

  function on(evt, handler) {
    events[evt] = events[evt] || []
    events[evt].push({
      handler: handler
    })
  }

  function fire(evt, args) {
    if (!events[evt]) {
      return
    }
    for (var i = 0; i < events[evt].length; i++) {
      events[evt][i].handler(args)
    }
  }

  function off(evt) {
    delete events[evt]
  }
  return {
    on: on,
    fire: fire,
    off: off
  }
})()

EventCenter.on('change', function (val) {
  console.log('change...  now val is ' + val)
})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容