三分钟学JS设计模式(四)工厂模式
程序员文章站
2022-03-21 08:35:28
工厂模式一、什么是工厂模式工厂模式(Factory Pattern)是最常用的设计模式之一。创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。举个栗子:老王开了家马铃薯加工厂。有一天对负责人说:我要生产薯片,于是工厂生产出薯片。第二天,对负责人说:我要吃薯条,于是生产出薯条。期间老王根本不用知道工厂怎么生产,只需要说要什么。这就是工厂模式。二、 优缺点优点:1、简单易用:调用者只需要知道名称就能创建对应的对象,调用者只关心接口,实现逻辑都在工厂里面。2、可...
工厂模式
一、什么是工厂模式
工厂模式(Factory Pattern)是最常用的设计模式之一。创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
举个栗子:老王开了家马铃薯加工厂。有一天对负责人说:我要生产薯片,于是工厂生产出薯片。第二天,对负责人说:我要吃薯条,于是生产出薯条。期间老王根本不用知道工厂怎么生产,只需要说要什么。这就是工厂模式。
二、 优缺点
- 优点:
- 1、简单易用:调用者只需要知道名称就能创建对应的对象,调用者只关心接口,实现逻辑都在工厂里面。
- 2、可拓展:想增加一个产品,只要扩展工厂类(方法)。
- 缺点
- 1、因为可拓展,这个工厂会越来越大,增加系统复杂性
三、场景例子、代码实现
场景:不同的账号类型登陆菜单不一样,根据不同类型返回不同的权限
- 不用工厂,散装代码:
获取权限跟其他业务逻辑混在一起,代码可读性差,后续维护的人没办法一下子找到对应的业务逻辑代码,骂骂咧咧地改起代码
// 工厂方法,获取当前用户的角色名和权限
var user = null;
switch(userType){
case 'ADMIN':
user = { role:'管理员',menu:['用户管理','订单查询','首页'] }
break;
case 'COMMON_USER'
user = { role:'普通用户',menu:['订单查询','首页'] }
break;
default:
user = { role:'游客',menu:['首页'] }
}
// 渲染user balabala
- 引入工厂方法
跟上面的一比,代码满足单一性原则,看起来清晰多了。
// 工厂方法,获取当前用户的角色名和权限
const factory = function(userType){
switch(userType){
case 'ADMIN':
return { role:'管理员',menu:['用户管理','订单查询','首页'] }
case 'COMMON_USER'
return { role:'普通用户',menu:['订单查询','首页'] }
default:
return { role:'游客',menu:['首页'] }
}
}
const user = factory('ADMIN');
// 渲染user balabala
- 配置字典
以上简单的工厂方法,我们还能写成字典:
const USER_MAP = {
ADMIN : { role:'管理员',menu:['用户管理','订单查询','首页'] },
COMMON_USER:{ role:'普通用户',menu:['订单查询','首页'] },
DEFAULT:{ role:'游客',menu:['首页'] }
}
const userType = 'ADMIN'
const user = USER_MAP[userType] || USER_MAP.DEFAULT ;
// 渲染user balabala
- 稍微复杂一点的
实际开发可能会有各种判断条件,我们尝试着加入vip、禁用功能:
// 工厂方法,获取当前用户的角色名和权限
const factory = function(option){
const { userType , isVip, disabled} = option
let result = {};
switch(userType){
case 'ADMIN':
result = { role:'管理员',menu:['用户管理','订单查询','首页'] }
break;
case 'COMMON_USER':
result = { role:'普通用户',menu:['订单查询','首页'] }
// 如果是普通用户VIP那么显示付费教程
if(isVip){
result.menu = result.menu.conact(['JS设计模式付费教程'])
}
break;
default:
result ={ role:'游客',menu:['首页'] }
break;
}
// 如果被禁用清除所有菜单
if(disabled){
result.menu = [];
}
return result;
}
const user = factory('COMMON_USER');
// 渲染user balabala
- 其他
著名的 React 源码中也使用了工厂方法,是不是觉得React源码也挺简单的呀?
/**
* Return a function that produces ReactElements of a given type.
* See https://reactjs.org/docs/react-api.html#createfactory
*/
function createFactory(type) {
const factory = createElement.bind(null, type);
// Expose the type on the factory and the prototype so that it can be
// easily accessed on elements. E.g. `<Foo />.type === Foo`.
// This should not be named `constructor` since this may not be the function
// that created the element, and it may not even be a constructor.
// Legacy hook: remove it
factory.type = type;
return factory;
}
本文地址:https://blog.csdn.net/xiaolongbaobushibao/article/details/110878202