本回内容介绍

上一回聊到JS单例模式(singleton),做了一道题,内容不多,比较容易理解。
介一回嘞,聊聊工厂模式,之前聊到过工厂模式,这回聊深入点儿,可能会比较抽象,不过好在实际开发中使用还算广泛,理解起来会比较容易,开始咯:

1. 简单工厂

比如我们创建一个会员系统,有会员和管理员两种角色,每种角色有登录,注销的功能,
这里需要引入之前讲过的接口类,如下:

// 用户类
function User(){};// 用户工厂模式
User.prototype = {// 还原构造器,指向Userconstructor: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:

2. 简单工厂之解耦

这里要用到之前写的继承类了,写一个用户基类,还要考虑到每个用户和管理员分别有不同的权限,那么我们可以再做一次工厂解耦,细化粒度,如下:

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:

3. 简单工厂之抽象类

不同的用户组有不同的角色,不同的角色拥有不同的权限,如下:

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();

这个例子有点略复杂,在上一个例子的基础上做了抽象类,还复习了装饰者模式,如果感觉晕菜,可以跳过。
这里其实还可以进一步优化,达到高聚类低耦合,这里工厂模式就告一段落了。


装个逼先。今天看优酷放出了新版嘻哈四重奏,一看没有了原版人马,就算是笑点也笑不起来了,算了换一个剧看,啊呃~~

这一回聊的内容比较绕脑袋,反正感觉晕菜的话就启动囫囵吞枣模式,想不通的先停下,以后再回过来看或许就恍然大悟,
下面的内容,跟上一回一样,就一道题好了。

题目:快速排序

这个快速排序比较基础,网上很多,这里我就把注释写清楚一点,方便大家理解:

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

网上找的例子,注释写的还算清楚吧,难度不大,跟上一回一样,当娱乐消遣。

这一回,主要聊了工厂模式,并且将前面的内容融合了进去,复习了继承,接口,单例模式,装饰者模式,涉及了一些简单的业务逻辑,对于刚接触面向对象,设计模式的童鞋稍微有点难度~~
下一回,就聊用的比较频繁的一个设计模式,门面模式。

客观看完点个赞,推荐推荐呗,嘿嘿~~


注:此系飞狐原创,转载请注明出处

听飞狐聊JavaScript设计模式系列07相关推荐

  1. 听飞狐聊JavaScript设计模式系列11

    本回内容介绍 上一回,聊了适配器模式,图片预加载,介一回,聊桥接模式(Bridge),跟之前一样,难度比较小,桥接模式将抽象部分与它的实现部分分离,通过桥接模式联系彼此,同时又使之都可以独立地变化.也 ...

  2. 听飞狐聊JavaScript设计模式系列05

    本回内容介绍 上一回聊到JS的类的模拟,继承,分析了nodejs,extjs,jquery,underscore的继承源码. 介一回,偶们来聊一下在JS中模拟接口,掺元类,装饰者模式,有些盆友可能用过 ...

  3. 听飞狐聊JavaScript设计模式系列13

    本回内容介绍 上一回聊了聊组合模式(Composite),用组合模式模拟了个图片库,聊了递归. 介一回聊状态模式(State),官方描述允许一个对象在其内部状态改变时改变它的行为.略抽象,不过看了代码 ...

  4. JavaScript设计模式系列—模式篇总结(上)

    转载请注明预见才能遇见的博客:http://my.csdn.net/ 原文地址:https://blog.csdn.net/pcaxb/article/details/102517956 JavaSc ...

  5. JavaScript设计模式系列四之外观模式(附案例源码)

    文章初衷 设计模式其实旨在解决语言本身存在的缺陷, 目前javaScript一些新的语法特性已经集成了一些设计模式的实现, 大家在写代码的时候,没必要为了用设计模式而去用设计模式, 那么我这边为什么还 ...

  6. javascript设计模式系列 - LukeLin - 博客园

    javascript设计模式系列 创建型: 1.抽象工厂模式(Abstract Factory) 2.构建者模式(Builder) 3.工厂方法模式(Factory Method) 4.原型模式(Pr ...

  7. javascript设计模式系列

    创建型: 1.抽象工厂模式(Abstract Factory) 2.构建者模式(Builder) 3.工厂方法模式(Factory Method) 4.原型模式(Prototype) 5.单例模式(S ...

  8. JavaScript进阶系列01,函数的声明,函数参数,函数闭包

    本篇主要体验JavaScript函数的声明.函数参数以及函数闭包. □ 函数的声明 ※ 声明全局函数 通常这样声明函数: function doSth() { alert("可以在任何时候调 ...

  9. JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

最新文章

  1. 【数论总结】-----励志写好一篇数论总结↖(^ω^)↗//正在施工...未完工
  2. python科学计算基础教程pdf下载-python科学计算 第二版 PDF 下载
  3. Keras之ML~P:基于Keras中建立的简单的二分类问题的神经网络模型(根据200个数据样本预测新的5个样本)——概率预测
  4. MySQL数据类型:UNSIGNED注意事项
  5. gevent模块的使用
  6. Python返回数组(List)长度的方法
  7. HTML5关于上传API的一些使用(上)
  8. Vue项目中使用eslint的笔录,编辑器采用sublime3
  9. 雷达信号处理基础 多普勒频移
  10. c语言实验报告评语大全,实验报告总结
  11. acme申请证书报错:Please update your account with an email address first.的修复方法
  12. 在浏览器输入URL,按下回车之后的流程?
  13. 5. DR与BDR选举
  14. 程序员快速记忆英文单词的专属诀窍
  15. 2020最难求职年,程序员职场面试 “防坑指南” ,全员必备!
  16. win10 远程桌面和向日葵远控哪个好用?
  17. Unity3D分离子物体解除父子关系/也可实现对子物体的删除
  18. Authentication and Authorization授权与验证
  19. C语言每日一练 —— 第20天:位运算
  20. VIP看剧也要找好友砍一刀!网友喊话优酷:吃相越来越难看了

热门文章

  1. git HEAD detached from origin 问题的解决
  2. Linux oracle中文乱码的问题解决
  3. WebApi接口访问异常问题。尝试创建“testController”类型的控制器时出错。请确保控制器具有无参数公共构造函数
  4. Mysql 时间格式默认空串 ‘0000-00-00 00:00:00‘ select抛出异常的解决方法
  5. “ void 0”是什么意思? [重复]
  6. 用Python编写单元测试:如何开始? [关闭]
  7. Shell命令对整数求和,每行一个?
  8. 数据库连接池配置和优化
  9. win11没有uefi如何安装 windows11跳过uefi模式的安装方法
  10. 思科计算机网络第四章考试,思科网络学院第期第四章.docx