設計模式並不是某一種語言所特有的,而是一種設計理念,本文學習Javascript的設計模式中的工廠設計模式相關知識。音樂播放器的prototype屬性可以封裝成一個對象,用作父類繼承。建立工廠動態生成WangyiMusic或者QQMusic,然後生成一個QQMusic實例,並調用相應的方法。 ...
設計模式並不是某一種語言所特有的,而是一種設計理念,現在學習Javascript的設計模式相關知識點。
工廠模式
工廠模式設計目標是:根據不同的需求創建實例化對象。我們將通過一個特定的需求來逐漸深入的講解工程模式的用法。
我們需要達到的一個需求是,做一個音樂播放器,這個播放器有四個按鈕,分別是上一首、下一首、播放暫停、靜音。
針對上面的需求,我們先按照最簡單的工廠模式寫一個方法。
1 <script> 2 function WangyiMusicAction(action) { 3 var obj = new Object; 4 obj.vender = "網易雲音樂"; 5 obj.playingMusic = "see you again"; 6 7 switch (action) { 8 case "last": 9 obj.information = { currentMusic: "小幸運", status: "200|404", message: "上一曲" }; 10 break; 11 case "next": 12 obj.information = { currentMusic: "野子", status: "200|404", message: "下一曲" }; 13 break; 14 case "play": 15 obj.information = { currentMusic: "see you again", status: "200|500", message: "播放" }; 16 break; 17 case "mute": 18 obj.information = { currentMusic: "see you again", status: "200|500", message: "靜音" }; 19 break; 20 } 21 22 return obj; 23 }; 24 25 /***下麵是調用測試代碼***/ 26 var music = new WangyiMusicAction("next"); 27 console.log("音樂提供商:" + music.vender); // 網易雲音樂 28 console.log("正在播放:" + music.playingMusic); // see you again 29 console.log("執行動作:" + music.information.message); // 下一曲 30 console.log("介面狀態:" + music.information.status); // 200|404 31 console.log("執行動作後歌曲:" + music.information.currentMusic); //野子 32 33 </script>
通過給action傳遞不同的參數,可以獲取不同的播放器狀態。
面向對象理念
但是上述的方法並沒有用到面向對象的理念,我們使用面向對象的思維重新修改上面的方法。
1 <script> 2 var WangyiMusicAction = function () { 3 this.vender = "網易雲音樂"; 4 this.playingMusic = "see you again"; 5 }; 6 7 //擴展其prototype屬性 8 WangyiMusicAction.prototype = { 9 last: function () { 10 this.information = { currentMusic: "小幸運", status: "200|404", message: "上一曲" }; 11 }, 12 next: function () { 13 this.information = { currentMusic: "野子", status: "200|404", message: "下一曲" }; 14 }, 15 play: function () { 16 this.information = { currentMusic: "see you again", status: "200|500", message: "播放" }; 17 }, 18 mute: function () { 19 this.information = { currentMusic: "see you again", status: "200|500", message: "靜音" }; 20 } 21 }; 22 23 24 /***下麵是調用測試代碼***/ 25 var music = new WangyiMusicAction(); 26 console.log("音樂提供商:" + music.vender); // 網易雲音樂 27 console.log("正在播放:" + music.playingMusic); // see you again 28 29 music.next(); // 執行下一曲動作 30 console.log("執行動作:" + music.information.message); // 下一曲 31 console.log("介面狀態:" + music.information.status); // 200|404 32 console.log("執行動作後歌曲:" + music.information.currentMusic); //野子 33 34 </script>
在上述面向對象的工廠模式中,建立一個WangyiMusicAction對象,然後擴展其prototype屬性,這樣每個實例都會有自己的方法。
改進工廠模式
上面的工廠模式中,只能生成WangyiMusicAction的對象,如果我還要生成一個QQMusic和BaiduMusic,XiamiMusic,只有每個music都得寫一遍方法,這是不值得推薦的。
我們可以通過一個Factory來動態創建各種類型的Music,首先是WangyiMusicAction。
優化工廠模式
但是在上面的工廠模式中,我們發現對於不同音樂提供商共用的屬性可以封裝成一個對象,用作父類繼承。
1,定義父類
2,繼承
通過修改prototype屬性實現繼承。
3,建立Factory工廠
建立工廠動態生成WangyiMusic或者QQMusic,然後生成一個QQMusic實例,並調用相應的方法。
1 <script> 2 //基類(父類)Music方法 3 var BaseMusic = function () { 4 this.playingMusic = "see you again"; 5 this.information = { 6 currentMusic: "", 7 status: "", 8 message: "" 9 }; 10 }; 11 12 //實現通用方法 13 BaseMusic.prototype = { 14 last: function () { 15 this.information.currentMusic = "小幸運"; 16 this.information.status = "200|404"; 17 this.information.message = "上一曲"; 18 }, 19 next: function () { 20 this.information.currentMusic = "野子"; 21 this.information.status = "200|404"; 22 this.information.message = "下一曲"; 23 }, 24 play: function () { 25 this.information.currentMusic = "see you again"; 26 this.information.status = "200|500"; 27 this.information.message = "播放"; 28 }, 29 mute: function () { 30 this.information.currentMusic = "see you again"; 31 this.information.status = "200|500"; 32 this.information.message = "靜音"; 33 } 34 }; 35 36 37 //網易雲音樂不同於父類的構造方法 38 var WangyiMusicAction = function (action) { 39 this.vender = "網易雲音樂"; 40 }; 41 //通過prototype實現類繼承 42 WangyiMusicAction.prototype = new BaseMusic(); //將動作放在基類,到達代碼復用的目的 43 44 //QQ音樂不同於父類的構造方法 45 var QQMusicAction = function (action) { 46 this.vender = "QQ音樂"; 47 }; 48 //通過prototype實現類繼承 49 QQMusicAction.prototype = new BaseMusic(); //將動作放在基類,到達代碼復用的目的 50 51 52 //音樂工廠 53 var MusicFactory = function (type) { 54 switch (type) { 55 case "wangyi": 56 return new WangyiMusicAction(); 57 case "qq": 58 return new QQMusicAction(); 59 } 60 }; 61 62 /***下麵是調用測試代碼***/ 63 var music = new MusicFactory("wangyi"); 64 console.log("音樂提供商:" + music.vender); 65 console.log("正在播放:" + music.playingMusic); 66 67 music.next(); // 執行下一曲動作 68 console.log("執行動作:" + music.information.message); 69 console.log("介面狀態:" + music.information.status); 70 console.log("執行動作後歌曲:" + music.information.currentMusic); 71 72 </script>
通過上述的繼承父類方案,可以優化代碼結構,工廠模式也使用的更加簡潔。