設(shè)計模式

1.單例模式
保證全局只有一個實例,節(jié)省資源畅形,類似java的靜態(tài)類 static养距,一般用到的地方有歷史記錄、線程池等等

let Singleton=function(){
  this.name=1
}
//因為javascript 沒有靜態(tài)類的標(biāo)識 故用閉包保持唯一性 外部無法訪問instance
Singleton.getInstance=(function(){
  let instance=null
  return function(){
    if(!instance ){
        instance=new Singleton()
    }
    return instance
  }
})()

let s1=Singleton.getInstance()
let s2=Singleton.getInstance()
console.log(s1===s2)//true
console.log(s1.name)//1
s1.name=2
console.log(s1.name)//2
console.log(s2.name)//2

2.策略類
比如算法日熬,各種算法封裝在策略類棍厌,各種方法的使用交給環(huán)境類
看代碼:


let strategy={
  //冒泡排序 逐個調(diào)換位置
  A(numbers){
    for(let i=0;i<numbers.length;i++){
      for(let j=0;j<numbers.length;j++){
        let itemNext=numbers[j+1]
        let item=numbers[j]
        if(itemNext<item){
            numbers[j+1]=item
            numbers[j]=itemNext
        }
      }
    }
    return numbers
  },
  //選擇排序 每次循環(huán)把最小的放入前置位
  B(numbers){
    for(let i=0;i<numbers.length;i++){
      let itemI=numbers[i]
      for(let j=i+1;j<numbers.length;j++){
        let itemJ=numbers[j]
        if(itemI>itemJ){
            numbers[i]=itemJ
            numbers[j]=itemI
            itemI=itemJ
        }
      }
    }
    return numbers
  }
}
let content=name=>{
  let numbers=[1,3,5,6,1,3,4,6,5]
  return strategy[name](numbers)
}
console.log(content('A'))
console.log(content('B'))

3.代理模式
高度解耦,對象保護竖席,易修改耘纱,因為是代理,所以會慢一點
示例代碼:

let myImg={
  setSrc(img,src){
    img.src=src
  }
}

let proxyImg={
  setImg(imgNode,src){
    //實現(xiàn)圖片懶加載
    myImg.setSrc(imgNode,'默認(rèn)圖.png')//占位圖片
    let img=new Image()
    imgNode.onLoad=function(){
      myImg.setSrc(imgNode,src)
    }
    img.src=src//真正要加載的產(chǎn)品圖片
  }
}
let imgNode=document.crateElement('img')
let imgUrl='產(chǎn)品圖.png'
document.body.append(imgUrl)

proxyImg.setImg(imgNode,imgUrl)

4.迭代器模式
迭代器模式是指提供一種方法順序訪問一個集合對象的各個元素毕荐,使用者不需要了解集合對象的底層實現(xiàn)束析。
不太清楚其用途~

let Iterator=obj=>{
  let current=0;
  let next = ()=>current+=1
  let end = ()=>current>=obj.length
  let get = ()=>obj[current]
  return{
    next,
    end,
    get
  }
}
let myIter = Iterator([1, 2, 3]);
while(!myIter.end()) { 
  console.log(myIter.get()) myIter.next(); 
}

5.訂閱發(fā)布模式
訂閱-發(fā)布模式定義了對象之間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時憎亚,所有依賴它的對象都可以得到通知员寇。

event.js
class Event{
  constructor(){
    this._cbs={}
  }
  //訂閱
  on(key,fn){
    if(typeof fn != "function"){
      return false
    }
    this._cbs = this._cbs || {};
    (this._cbs[key] = this._cbs[key] || []).push(fn)
  }
  //發(fā)布
  emit(){
     let _cbs=this._cbs
     let key=Array.prototype.shift.apply(arguments)
     let affair =_cbs[key]||[]
     if(!affair||affair.length<1){
      return false
     }
     for(let fn of affair){
       fn.apply(null,arguments)
     }
     return true
  }
  //銷毀
  off(key,fn){
    this._cbs = this._cbs || {}
    // all
    if (!arguments.length) {
      this._cbs = {}
      return true
    }
    var callbacks = this._cbs[key]
    if (!callbacks) return
    // remove all handlers
    if (arguments.length === 1) {
      delete this._cbs[key]
      return true
    }
 // remove specific handler
    var cb
    for (var i = 0, len = callbacks.length; i < len; i++) {
      cb = callbacks[i]
      if (cb === fn || cb.fn === fn) {
        callbacks.splice(i, 1)
        break
      }
    }
    return true
  }
}

export default Event
  //a.js
  import Event from event.js
  let e=new Event()
  e.on('one',v=>{
    console.log('訂閱')
    console.log(v)
  })

   e.emit('one',1000)
   e.off('one')
   e.emit('one',1000)

6.工廠模式
工廠方法模式的實質(zhì)是“定義一個創(chuàng)建對象的接口弄慰,但讓實現(xiàn)這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行蝶锋÷剿” 簡單來說:就是把new對象的操作包裹一層,對外提供一個可以根據(jù)不同參數(shù)創(chuàng)建不同對象的函數(shù)扳缕。

class Dog{
  run(){
      console.log('狗')
  }
}

class Cat{
  run(){
      console.log('貓')
  }
}

class Animal{
  constructor(name){
    name = name.toLocaleLowerCase()
    switch(name){
      case 'cat':
        return new Dog()
      case 'dog':
        return new Cat()
      default:
        console.log('沒有哦')
    }
  }
}

let ss=new Animal('cat')
ss.run()

7.組合模式
用小的子對象構(gòu)造更大的父對象慌闭,而這些子對象也由更小的子對象構(gòu)成 單個對象和組合對象對于用戶暴露的接口具有一致性,而同種接口不同表現(xiàn)形式亦體現(xiàn)了多態(tài)性

// 文件類
class File {
  constructor(name) {
    this.name = name || "File";
  }

  add() {
    throw new Error("文件夾下面不能添加文件");
  }

  scan() {
    console.log("掃描文件: " + this.name);
  }
}

// 文件夾類
class Folder {
  constructor(name) {
    this.name = name || "Folder";
    this.files = [];
  }

  add(file) {
    this.files.push(file);
  }

  scan() {
    console.log("掃描文件夾: " + this.name);
    for (let file of this.files) {
      file.scan();
    }
  }
}

let home = new Folder("用戶根目錄");

let folder1 = new Folder("第一個文件夾"),
  folder2 = new Folder("第二個文件夾");

let file1 = new File("1號文件"),
  file2 = new File("2號文件"),
  file3 = new File("3號文件");

// 將文件添加到對應(yīng)文件夾中
folder1.add(file1);

folder2.add(file2);
folder2.add(file3);

// 將文件夾添加到更高級的目錄文件夾中
home.add(folder1);
home.add(folder2);

// 掃描目錄文件夾
home.scan();

8.享元模式
享元模式:運用共享技術(shù)來減少創(chuàng)建對象的數(shù)量躯舔,從而減少內(nèi)存占用驴剔、提高性能。

class ObjectPool{
  constructor(){
    this._pool=[]
  }
  create(obj){
    return this._pool.length===0?
    new obj(this):
    this._pool.shift()
  }
  recover(obj){
    return this._pool.push(obj);
  }
  // 對象池大小 
  size() { 
    return this._pool.length; 
  }
}

// 模擬文件對象
class File {
  constructor(pool) {
    this.pool = pool;
  }

  // 模擬下載操作
  download() {
    console.log(`+ 從 ${this.src} 開始下載 ${this.name}`);
    setTimeout(() => {
      console.log(`- ${this.name} 下載完畢`); // 下載完畢后, 將對象重新放入對象池
      this.pool.recover(this);
    }, 100);
  }
}

/****************** 以下是測試函數(shù) **********************/

let objPool = new ObjectPool();

let file1 = objPool.create(File);
file1.name = "文件1";
file1.src = "https://download1.com";
file1.download();

let file2 = objPool.create(File);
file2.name = "文件2";
file2.src = "https://download2.com";
file2.download();

setTimeout(() => {
  let file3 = objPool.create(File);
  file3.name = "文件3";
  file3.src = "https://download3.com";
  file3.download();
}, 200);

setTimeout(
  () =>
    console.log(
      `${"*".repeat(50)}\n下載了3個文件庸毫,但其實只創(chuàng)建了${objPool.size()}個對象`
    ),
  1000
);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仔拟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子飒赃,更是在濱河造成了極大的恐慌利花,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件载佳,死亡現(xiàn)場離奇詭異炒事,居然都是意外死亡,警方通過查閱死者的電腦和手機蔫慧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門挠乳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姑躲,你說我怎么就攤上這事睡扬。” “怎么了黍析?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵卖怜,是天一觀的道長。 經(jīng)常有香客問我阐枣,道長马靠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任蔼两,我火速辦了婚禮甩鳄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘额划。我一直安慰自己妙啃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布俊戳。 她就那樣靜靜地躺著揖赴,像睡著了一般茁瘦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上储笑,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音圆恤,去河邊找鬼突倍。 笑死,一個胖子當(dāng)著我的面吹牛盆昙,可吹牛的內(nèi)容都是我干的羽历。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼淡喜,長吁一口氣:“原來是場噩夢啊……” “哼秕磷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炼团,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤澎嚣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瘟芝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體易桃,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年锌俱,在試婚紗的時候發(fā)現(xiàn)自己被綠了晤郑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钙蒙。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡伦连,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搅吁,到底是詐尸還是另有隱情吭练,我是刑警寧澤诫龙,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站线脚,受9級特大地震影響赐稽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜浑侥,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一姊舵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寓落,春花似錦括丁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尖昏。三九已至,卻和暖如春构资,著一層夾襖步出監(jiān)牢的瞬間抽诉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工吐绵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留迹淌,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓己单,卻偏偏與公主長得像唉窃,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纹笼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

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