博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
听飞狐聊JavaScript设计模式系列07
阅读量:6574 次
发布时间:2019-06-24

本文共 6029 字,大约阅读时间需要 20 分钟。

本回内容介绍

上一回聊到JS单例模式(singleton),做了一道题,内容不多,比较容易理解。

介一回嘞,聊聊工厂模式,之前聊到过工厂模式,这回聊深入点儿,可能会比较抽象,不过好在实际开发中使用还算广泛,理解起来会比较容易,开始咯:

1. 简单工厂

比如我们创建一个会员系统,有会员和管理员两种角色,每种角色有登录,注销的功能,

这里需要引入之前讲过的接口类,如下:

// 用户类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:

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;    }}// 跟上面一样,这里定义Adminfunction 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

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

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

下一回,就聊用的比较频繁的一个设计模式,门面模式。

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


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

你可能感兴趣的文章
printk()函数的总结
查看>>
MySQL: ON DUPLICATE KEY UPDATE 用法
查看>>
接口与抽象类的应用(包括各自设计模式)
查看>>
使用 Ghost 写博客
查看>>
c#:拖动功能
查看>>
Centos6.9下安装并使用VNC的操作记录
查看>>
《Linux内核设计与实现》读书笔记 - 目录 (完结)
查看>>
GIS-013-Cesium Terrain 数据生成
查看>>
java int与integer的区别
查看>>
UVALive3902 Network[贪心 DFS&&BFS]
查看>>
图像处理的基本概念
查看>>
039 hive中关于数据库与表等的基本操作
查看>>
Java Volatile关键字 以及long,double在多线程中的应用
查看>>
__slots__用法以及优化
查看>>
分部积分的图形解释
查看>>
idea常用快捷键大全(转)
查看>>
HashMap和Hashtable的区别 源码分析
查看>>
Git初始化仓库
查看>>
mysql利用timestamp来进行帖子排序
查看>>
SQL Server 管理常用的SQL和T-SQL
查看>>