上一回聊到JS單例模式(singleton),作了一道題,內容很少,比較容易理解。
介一回嘞,聊聊工廠模式,以前聊到過工廠模式,這回聊深刻點兒,可能會比較抽象,不過好在實際開發中使用還算普遍,理解起來會比較容易,開始咯:javascript
好比咱們建立一個會員系統,有會員和管理員兩種角色,每種角色有登陸,註銷的功能,
這裏須要引入以前講過的接口類,以下:java
// 用戶類 function User(){}; // 用戶工廠模式 User.prototype = { // 還原構造器,指向User constructor:User, // 建立用戶的方法,傳入的type是用戶類型 createUser:function(type){ // 這裏建一個變量,用於返回實例 var user; // 判斷傳入的用戶類型,返回該類型的實例 switch(type){ case 'Member':user = new Member();break; case 'Admin' :user = new Admin();break; }; // 這裏以前講過的,檢測接口 Interface.ensureImplements(user,UserInterface) return user; } } // 建立一個用戶接口,並且必須實現該接口的login,logout兩個方法 var UserInterface = new Interface('UserInterface',['login','logout']); // 會員類,包括實現的接口方法 function Member(){} Member.prototype.login = function(){alert('會員登陸');} Member.prototype.logout = function(){alert('會員註銷');} // 管理員類,包括實現的接口方法 function Admin(){} Admin.prototype.login = function(){alert('管理員登陸');} Admin.prototype.logout = function(){alert('管理員註銷');} // new一個用戶工廠 var o = new User(); // 建立一個管理員 var a = o.createUser("Admin"); // 調用login方法 a.login(); // 下面一堆是會員的實現,不用多說了吧 var o2 = new User(); var m = o.createUser("Member"); m.logout();
這就是一個簡單工廠模式實現了,應該不少盆友已經看出來了,一樣的方法要實現兩次,好像有點冗餘了吧,那麼就能夠用到以前的繼承了,改吧改吧,帥狐show time:設計模式
這裏要用到以前寫的繼承類了,寫一個用戶基類,還要考慮到每一個用戶和管理員分別有不一樣的權限,那麼咱們能夠再作一次工廠解耦,細化粒度,以下:數組
function User(){}; User.prototype = { constructor:User, // 給用戶配置權限,type是用戶類型 assignRole:function(type){ // 建立用戶,這裏還能夠作不少擴展,這裏先留... var user = UserFactory.createUser(type); return user; } } // 建立用戶的工廠(還記的上一回的單例模式嗎,這也是個單例模式喲) var UserFactory = { // 這裏爲了解耦,跟上面的代碼對比一下,換了個位置 createUser:function(type){ var user; switch(type){ case 'Member':user = new Member();break; case 'Admin' :user = new Admin();break; }; Interface.ensureImplements(user,UserInterface) return user; } } var UserInterface = new Interface('UserInterface',['login','logout']); // User的基類,若是有疑惑,看看以前講的繼承 function BaseUser(){}; BaseUser.prototype = { constructor:BaseUser, login:function(){ alert(this.constructor.name + ' 登陸'); }, logout:function(){ alert(this.constructor.name + ' 註銷'); } } // 用戶類,繼承基類,這樣就有了兩個方法 function Member(){} extend(Member,BaseUser); // 管理員類,這樣就避免了重複建立的冗餘 function Admin(){} extend(Admin,BaseUser); // 這裏沒什麼好說的,實例測試 var o = new User(); var a = o.assignRole("Admin"); a.login(); var o2 = new User(); var m = o.assignRole("Member"); m.logout();
這個例子稍微開始有點複雜了,結合了以前聊的接口,繼承,單例等,在配置權限的地方其實還能夠作不少擴展,好比:
有會員有不一樣等級的會員,管理有不一樣等級的管理員,不一樣的級別存在不一樣的方法,要作到這樣的話,咱們能夠經過抽象類,讓每一個類覆蓋方法,動態的建立工廠,來吧,繼續帥狐show time:ide
不一樣的用戶組有不一樣的角色,不一樣的角色擁有不一樣的權限,以下:測試
function User(){}; User.prototype = { constructor:User, // 這裏是個抽象方法,每一個類能夠根據不一樣的需求來重載 assignRole:function(type){ // 調用自身的抽象方法,意義是在無重載的時候執行 this.abs(type); }, // 這裏是在無重載的時候執行 abs:function(){ throw new Error('the abstract class can override the virtual method with an abstract method.'); } }; // 單獨定義Member組 function MemberGroup(){} extend(MemberGroup,User); MemberGroup.prototype = { constructor:MemberGroup, // 分配權限方法,根據傳入的角色來建立不一樣的實例 assignRole:function(type){ var role; // 這裏定義兩個角色,會員和高級會員 var group = ['Member','SeniorMember']; // indexOf眼熟吧,第一回的時候聊過的ES5的新玩意 if(group.indexOf(type)>-1){ // 調用用戶工廠的建立用戶方法 role = UserFactory.createUser(type); }else{ alert('無該'+type+'角色!'); } return role; } } // 跟上面同樣,這裏定義Admin function AdminGroup(){} extend(AdminGroup,User); AdminGroup.prototype = { constructor:AdminGroup, assignRole:function(type){ var role; // 這裏定義兩個角色,管理員和高級管理員 var group = ['Admin','SeniorAdmin']; if(group.indexOf(type)>-1){ role = UserFactory.createUser(type); }else{ alert('無該'+type+'角色!'); } return role; } } // 建立用戶的工廠(跟上一個例子同樣,只是這裏是動態建立工廠) var UserFactory = { createUser:function(type){ // eval()直接執行 var user = eval('new '+type+'()'); Interface.ensureImplements(user,UserInterface) return user; } } var UserInterface = new Interface('UserInterface',['login','logout']); // User的基類,若是有疑惑,看看以前講的繼承 function BaseUser(){}; BaseUser.prototype = { constructor:BaseUser, login:function(){ alert(this.constructor.name + ' 登陸'); }, logout:function(){ alert(this.constructor.name + ' 註銷'); } } // 會員類,繼承基類,這樣就有了兩個方法 function Member(){} extend(Member,BaseUser); // 高級會員類,有本身特有的高級方法 function SeniorMember(){} extend(SeniorMember,BaseUser); SeniorMember.prototype.seniorM = function(){alert('高級會員的權限')}; // 管理員類,這樣就避免了重複建立的冗餘 function Admin(){} extend(Admin,BaseUser); // 高級管理員類,有本身特有的高級方法 function SeniorAdmin(){} extend(SeniorAdmin,BaseUser); SeniorAdmin.prototype.seniorA = function(){alert('高級管理員的權限')}; // 這裏其實能夠回憶一下裝飾者模式,把高級管理員的實例作一次包裝 var obj = new SeniorAdmin(); // 超級管理員類,裝飾高級管理員的實例 function SuperAdmin(obj){} SuperAdmin.prototype.superA = function(){ obj.seniorA(); alert('再彈一個窗,特效,特效,加特效!由於我是超級管理員!喲呼~~'); }; // 這裏沒什麼好說的,實例測試 var o = new MemberGroup(); var a = o.assignRole("SeniorMember"); a.seniorM(); var o2 = new AdminGroup(); var m = o2.assignRole("SeniorAdmin"); m.seniorA(); var o3 = new SuperAdmin(obj); o3.superA();
這個例子有點略複雜,在上一個例子的基礎上作了抽象類,還複習了裝飾者模式,若是感受暈菜,能夠跳過。
這裏其實還能夠進一步優化,達到高聚類低耦合,這裏工廠模式就告一段落了。優化
裝個逼先。今天看優酷放出了新版嘻哈四重奏,一看沒有了原版人馬,就算是笑點也笑不起來了,算了換一個劇看,啊呃~~ui
這一回聊的內容比較繞腦殼,反正感受暈菜的話就啓動囫圇吞棗模式,想不通的先停下,之後再回過來看或許就恍然大悟,
下面的內容,跟上一回同樣,就一道題好了。this
這個快速排序比較基礎,網上不少,這裏我就把註釋寫清楚一點,方便你們理解:spa
var arr = [12,5,36,6,22,66]; // 快速排序 function quickSort(arr){ // 判斷數組長度,只有小等於1的時候返回 if(arr.length<=1){ return arr; } // 向下取整,也就是取一半的長度 var num = Math.floor(arr.length/2); // 取中間的那個數 var numValue = arr.splice(num,1); // 定義兩個數組作容器 var left = []; var right = []; // 循環數組 for(var i=0;i<arr.length;i++){ // 當小於中間數的時候,放到left數組,大於中間數則放到right數組 if(arr[i]<numValue){ left.push(arr[i]); }else{ right.push(arr[i]); } } // 遞歸調用,再將left數組,中間數還有right數組合併成一個新數組,而後返回這個新數組 return quickSort(left).concat([numValue],quickSort(right)); }; alert(quickSort(arr)); // 5,6,12,22,36,66
網上找的例子,註釋寫的還算清楚吧,難度不大,跟上一回同樣,當娛樂消遣。
這一回,主要聊了工廠模式,而且將前面的內容融合了進去,複習了繼承,接口,單例模式,裝飾者模式,涉及了一些簡單的業務邏輯,對於剛接觸面向對象,設計模式的童鞋稍微有點難度~~
下一回,就聊用的比較頻繁的一個設計模式,門面模式。
客觀看完點個贊,推薦推薦唄,嘿嘿~~
注:此係飛狐原創,轉載請註明出處