三分钟学JS设计模式(四)工厂模式

工厂模式

一、什么是工厂模式

工厂模式(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;
	}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值