欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

三分钟学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