JavaScript
js 设计模式-工厂模式
什么是工厂模式 当去买一个 🍔 的时候,无须得到 🍔 的原材料,只需要获得到 🍔 对应工厂模式:不暴露创建对象的具体逻辑,将创建对象的方法封装到一个函数中,这个函数就是一个工厂 工厂模式按照抽象程度可以分为:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式 什么时候用工厂模式 对实例的封装,使用 new 操作符时候可以考虑用工厂模式 身边的工厂模式 $(selector) $()就是一个…
什么是工厂模式 当去买一个 🍔 的时候,无须得到 🍔 的原材料,只需要获得到 🍔 对应工厂模式:不暴露创建对象的具体逻辑,将创建对象的方法封装到一个函数中,这个函数就是一个工厂 工厂模式按照抽象程度可以分为:1.简单工厂模式 2.工厂方法模式 3.抽象工厂模式 什么时候用工厂模式 对实例的封装,使用 new 操作符时候可以考虑用工厂模式 身边的工厂模式 $(selector) $()就是一个…
$()就是一个简单工厂模式
function jQuery() {}
jQuery.prototype.extend = function() {};
// ...
window.$ = function(selector) {
return new jQuery(selector);
};
function CreatePerson(name, age, sex) {
var obj = Object.create(null);
obj.name = name;
obj.age = age;
obj.sex = sex;
obj.getData = function() {
console.log(this.name, this.age, this.sex);
};
return obj;
}
function factory(name, age, sex) {
return new CreatePerson(name, age, sex);
}
var p1 = factory('express', 21, 1);
var p2 = factory('egg', 22, 0);
p1.getData();
p2.getData();
// 输出
// express 21 1
// egg 22 0
// 简单工厂模式
// 只需要一个正确的参数,就可以得到结果,不需要知道创建的过程
// 不同用户分配不同权限
// 如果角色变多,那么就getInstance变的很庞大,比较难维护,所以适用于创建对象较少的情况
class User {
//构造器
constructor(option) {
this.role = option.role;
this.limit = option.limit;
}
//静态方法
static getInstance(role) {
switch (role) {
case 'superAdmin':
return new User({
role: '超级管理员',
limit: ['首页', '通讯录', '发现页', '应用数据', '权限管理']
});
break;
case 'admin':
return new User({
role: '管理员',
limit: ['首页', '通讯录', '发现页', '应用数据']
});
break;
case 'user':
return new User({
role: '普通用户',
limit: ['首页', '通讯录', '发现页']
});
break;
default:
throw new Error('参数错误, 可选参数:superAdmin、admin、user');
}
}
}
let superAdmin = User.getInstance('superAdmin');
let admin = User.getInstance('admin');
let normalUser = User.getInstance('user');
console.log(superAdmin);
console.log(admin);
console.log(normalUser);
// 输出
// role: "超级管理员", limit['首页', '通讯录', '发现页', '应用数据', '权限管理']
// role: "管理员", limit['首页', '通讯录', '发现页', '应用数据']
// role: "普通用户", limit['首页', '通讯录', '发现页']
把实际创建对象放到子类中
// 工厂方法模式
// 把实际创建对象放到子类中,父类就是一个抽象类,ES6中没有 abstract修饰符,所以可以判断 new.target==父类的构造函数,抛出异常
class User {
//构造器
constructor(option = {}) {
if (new.target == User) {
throw new Error('父类是抽象类,不能直接调用,需要重写该方法');
}
this.role = option.role;
this.limit = option.limit;
}
}
class UserFactory extends User {
constructor(option) {
super(option);
}
create(role) {
switch (role) {
case 'superAdmin':
return new UserFactory({
role: '超级管理员',
limit: ['首页', '通讯录', '发现页', '应用数据', '权限管理']
});
break;
case 'admin':
return new UserFactory({
role: '管理员',
limit: ['首页', '通讯录', '发现页', '应用数据']
});
break;
case 'user':
return new UserFactory({
role: '普通用户',
limit: ['首页', '通讯录', '发现页']
});
break;
default:
throw new Error('参数错误, 可选参数:superAdmin、admin、user');
}
}
}
var userFactory = new UserFactory();
let superAdmin = userFactory.create('superAdmin');
let admin = userFactory.create('admin');
let normalUser = userFactory.create('user');
console.log(superAdmin);
console.log(admin);
console.log(normalUser);
// 输出
// role: "超级管理员", limit['首页', '通讯录', '发现页', '应用数据', '权限管理']
// role: "管理员", limit['首页', '通讯录', '发现页', '应用数据']
// role: "普通用户", limit['首页', '通讯录', '发现页']
// 抽象工厂模式
// 有了3中角色,这三种角色的注册方式可以是qq,微信,微博,那判断这个来源就可以放在父类做,让子类继承父类方法
class User {
//构造器
constructor(option = {}) {
if (new.target == User) {
throw new Error('父类是抽象类,不能直接调用,需要重写该方法');
}
this.role = option.role;
this.limit = option.limit;
this.type = '';
}
getFrom(type) {
switch (type) {
case 'weixin':
this.type = '来自微信';
break;
case 'qq':
this.type = '来自qq';
break;
case 'weibo':
this.type = '来自微博';
break;
default:
throw new Error('参数错误:来自火星');
}
}
}
class UserFactory extends User {
constructor(option = {}) {
super(option);
if (option.type) {
this.getFrom(option.type);
}
}
create(role) {
switch (role) {
case 'superAdmin':
return new UserFactory({
role: '超级管理员',
limit: ['首页', '通讯录', '发现页', '应用数据', '权限管理'],
type: 'weixin'
});
break;
case 'admin':
return new UserFactory({
role: '管理员',
limit: ['首页', '通讯录', '发现页', '应用数据'],
type: 'qq'
});
break;
case 'user':
return new UserFactory({
role: '普通用户',
limit: ['首页', '通讯录', '发现页'],
type: 'weibo'
});
break;
default:
throw new Error('参数错误');
}
}
}
var userFactory = new UserFactory();
let superAdmin = userFactory.create('superAdmin');
let admin = userFactory.create('admin');
let normalUser = userFactory.create('user');
console.log(superAdmin);
console.log(admin);
console.log(normalUser);
// 输出
// UserFactory {role: "超级管理员", limit: Array(5), type: "来自微信"}
// UserFactory {role: "管理员", limit: Array(4), type: "来自qq"}
// UserFactory {role: "普通用户", limit: Array(3), type: "来自微博"}
// Sub是子类,Sup是超类
function _extend(Sub, Sup) {
// 定义一个空函数
var F = function() {};
// 空函数原型为超类原型
F.prototype = Sup.prototype;
// 实例化空函数,把超类原型引用传递给子类原型
Sub.prototype = new F();
// 重置子类原型构造函数为子类本身
Sub.prototype.constructor = Sub;
// 在子类保存超类原型,避免子类与超类耦合
Sub.sup = Sup.prototype;
// 检测超类原型的构造函数是否为原型本身,如果是原型本身,重置超类原型构造函数为超类本身
if (Sup.prototype.constructor === Object.prototype.constructor) {
Sup.prototype.constructor = Sup;
}
}
// 大工厂
var BigFactory = function(product2) {
this.product1 = '手机';
this.product2 = product2;
this.get = function() {
console.log(`我是大工厂,我自己制作了${this.product1},我可以获取到小工厂制作的${this.product2}`);
};
};
// 大工厂的原型方法
BigFactory.prototype = {
constructor: BigFactory,
// 大工厂执行小工厂的制作动作
run: function() {
this.make().A();
},
make: function() {
// 制作由小工厂做
throw new Error('父类是抽象类,不能直接调用,需要重写该方法');
}
};
// 小工厂
var SmallFactory = function(product2) {
BigFactory.call(this, product2);
};
// 小工厂继承与大工厂
_extend(SmallFactory, BigFactory);
// 小工厂原型上有一个制作动作
SmallFactory.prototype.make = function() {
var that = this;
var A = function() {
console.log(`我是小工厂,我在制作${that.product2}`);
};
return {
A
};
};
var smallFactory = new SmallFactory('手机壳');
smallFactory.run();
smallFactory.get();
// 输出
// 我是小工厂,我在制作手机壳
// 我是大工厂,我自己制作了手机,我可以获取到小工厂制作的手机壳
smallFactory 是继承 BigFactory 的,smallFactory 的结构

class BigFactory {
constructor(product2) {
(this.product1 = '手机'), (this.product2 = product2);
}
get() {
console.log(`我是大工厂,我自己制作了${this.product1},我可以获取到小工厂制作的${this.product2}`);
}
run() {
this.make().A();
}
make() {
throw new Error('父类是抽象类,不能直接调用,需要重写该方法');
}
}
class SmallFactory extends BigFactory {
constructor(product2) {
super(product2);
}
make() {
var A = () => {
console.log(`我是小工厂,我在制作${this.product2}`);
};
return {
A
};
}
}
var smallFactory = new SmallFactory('手机壳');
smallFactory.run();
smallFactory.get();
// 输出
// 我是小工厂,我在制作手机壳
// 我是大工厂,我自己制作了手机,我可以获取到小工厂制作的手机壳
// vue路由例子
// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import Login from 'login.vue';
Vue.use(Router);
export default new Router({
routes: [
//重定向到登录页
{
path: '/',
redirect: '/login'
},
//登陆页
{
path: '/login',
name: 'Login',
component: Login
}
]
});
// router/routerFactor.js
import A from 'a.vue';
import B from 'b.vue';
import C from 'c.vue';
import D from 'd.vue';
class User {
//构造器
constructor(option = {}) {
if (new.target == User) {
throw new Error('父类是抽象类,不能直接调用,需要重写该方法');
}
this.role = option.role;
this.limit = option.limit;
this.route = [];
}
setLimit() {
for (let ele of this.limit) {
this.route.push(User.allRoute[ele]);
}
}
static allRoute = {
// A
a: {
path: '/a',
name: 'A',
component: A
},
// B
b: {
path: '/b',
name: 'B',
component: B
},
// C
c: {
path: '/user',
name: 'C',
component: C
},
// D
d: {
path: '*',
name: 'D',
component: D
}
};
}
class UserFactory extends User {
constructor(option) {
super(option);
if (option) {
this.setLimit();
}
}
create(role) {
switch (role) {
case 'superAdmin':
return new UserFactory({
role: '超级管理员',
limit: ['a', 'b', 'c', 'd']
});
break;
case 'admin':
return new UserFactory({
role: '管理员',
limit: ['b', 'c', 'd']
});
break;
case 'user':
return new UserFactory({
role: '普通用户',
limit: ['c', 'd']
});
break;
default:
throw new Error('参数错误, 可选参数:superAdmin、admin、user');
}
}
}
var userFactory = new UserFactory();
let superAdmin = userFactory.create('superAdmin');
let admin = userFactory.create('admin');
let normalUser = userFactory.create('user');
// 这样就把不同权限的路由获取到了
var result1 = superAdmin.route;
var result2 = admin.route;
var result3 = normalUser.route;
暂无评论
确认操作
请再次确认编辑图片
待上传图片 (剩余 0 张)
项目详情
确认评论邮箱
邀请制评论