// es5写法
function UserFactory(role){
/**
* @role 角色
* @pages 角色对应能看到的页面
*/
function User(role, pages){
this.role = role;
this.pages = pages;
}
switch(role) {
case "superAdmin":
return new User("superAdmin", "1,2,3,4");
break;
case "admin":
return new User("admin", "1,2,3");
break;
case "editor":
return new User("*editor*", "1,2");
break;
default:
throw new Error("参数错误!!!")
}
}
var user1 = UserFactory('superAdmin');
var user2 = UserFactory('admin');
var user3 = UserFactory('editor');
var user4 = UserFactory('zhangsan');
console.log(user1); // {pages: "1,2,3,4", role: "superAdmin"}
console.log(user2); // {pages: "1,2,3", role: "admin"}
console.log(user3); // {pages: "1,2", role: "editor"}
console.log(user4); // Uncaught Error: 参数错误!!!
// es6 使用类的写法
class User{
/**
* @role 角色
* @pages 角色对应能看到的页面
*/
constructor(role, pages) {
this.role = role;
this.pages = pages;
}
static UserFactory(role){
switch(role) {
case "superAdmin":
return new User("superAdmin", "1,2,3,4");
break;
case "admin":
return new User("admin", "1,2,3");
break;
case "editor":
return new User("editor", "1,2");
break;
default:
throw new Error("参数错误!!!")
}
}
}
var user1 = User.UserFactory('superAdmin');
var user2 = User.UserFactory('admin');
var user3 = User.UserFactory('editor');
// var user4 = User.UserFactory('zhangsan');
console.log(user1); // {pages: "1,2,3,4", role: "superAdmin"}
console.log(user2); // {pages: "1,2,3", role: "admin"}
console.log(user3); // {pages: "1,2", role: "editor"}
// console.log(user4); // Uncaught Error: 参数错误!!!
如上示例:一个后台管理页面,超级管理员(superAdmin)、管理员(admin)、编辑者(editor)分别有1234、123,12的页面权限,将其封装 在一个函数中,通过不同登陆人的状态获取对应的页面。即编写工厂函数,调用它,传入你期望的参数,获得对应的值。
这就是工厂模式的一个简单应用了。
由一个对象决定创建一种产品对象类的实例,主要用来创建同一对象
。
只需要一个正常的参数,就可以获得所需要的数据,无需知晓具体创建的细节,可以快速创建大量相似对象,没有重复代码。
总结:所以创建对象数量少,对象的创建逻辑不复杂的时候使用工厂模式。
class User{
/**
* @name 用户名
* @role 权限
* @pages 用户权限对应有的页面
*/
constructor(name, role, pages){
this.name = name;
this.role = role;
this.pages = pages;
}
}
class SuperAdmin extends User{
constructor(name){
super(name, 'superAdmin', [1,2,3,4])
}
}
class Admin extends User{
constructor(name){
super(name, 'admin', [1,2,3])
}
}
class Editor extends User{
constructor(name){
super(name, 'editor', [1,2])
}
}
function getUserPages(role){
switch(role) {
case "superAdmin":
return SuperAdmin;
break;
case "admin":
return Admin;
break;
case "editor":
return Editor;
break;
default:
throw new Error("参数错误!!!")
}
}
let userClass1 = getUserPages('superAdmin');
console.log(userClass1); // 对应超级管理员的类
let user1 = new userClass1('张三');
console.log(user1);// {name: "张三", pages: [1, 2, 3, 4] ,role: "superAdmin"}
let userClass2 = getUserPages('admin');
console.log(userClass2); // 对应管理员的类
let user2 = new userClass2('李四');
console.log(user2);// {name: "李四", pages: [1, 2, 3] ,role: "admin"}
let userClass3 = getUserPages('editor');
console.log(userClass3); // 对应编辑者的类
let user3 = new userClass3('王五');
console.log(user3);// {name: "王五", pages: [1, 2] ,role: "Editor"}
上述代码效果图如下
如上示例:同样是一个后台管理页面,超级管理员(superAdmin)、管理员(admin)、编辑者(editor)分别有1234、123,12的页面权限,抽象工厂模式先写了一个用户(user)类,含有其他用户的共同属性,将超级管理员、管理员、编辑者分别写了一个类并继承用户类,最后依旧使用了一个方法switch的时候返回的是对应的类,区别开来。抽象工厂函数就是为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
在工厂模式的加上一层抽象,工厂的工厂。只需要一个正常的参数,就可以获得所需要的数据,无需知晓具体创建的细节。
白话:抽象工厂模式并不直接生成示例,而是对产品类的创建。
抽象工厂函数就是为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
该不该使用用工厂,就要看它是否带来大量不必要的复杂性,带来不必要的开销(不为了用模式而用模式)。抽象工厂模式就是如果你要使用工厂模式的情况下,里面switch有多个(如10个)的判断逻辑,并且逻辑比较复杂的话,就可以使用。