每日一节设计模式(2) —— 创建型设计模式之简单工厂模式

大家好!让编码更加有趣,让生活更有逻辑,我是星球小顽童,欢迎来到我的世界,和我一起玩转星球!

简单工厂模式又叫静态工厂方法,由一个工厂对象来决定创建某一种产品对象类的实例。简单来说,主要就是用于创建同一类对象。

举个栗子:就以我们每一个项目的第一个开发步骤登录/注册模块来讲,

a. 登录模块,我们可能会有一份如下需求列表:

  1. 用户名输入框如果输入内容不符合规范显示自定义警示框提醒“用户名不合规”。
  2. 密码输入框如果输入密码错误显示自定义警示框提醒“密码不正确”。
  3. 用户名不存在显示自定义警示框提醒“用户名不存在”。
  4. 登录成功后弹出自定义提示框“登录成功,开始浪里个浪...”.

针对需求,如果对面向对象还不太了解的同学可能会这样来写:

const LoginTip = function(tip) {
   this.content = tip
}

LoginTip.prototype.show = function() {
   const box = document.getElementById('tipBox');
   box.style.display = 'block';
   box.innerText = this.content;
}

const  userNameTip = new LoginTip('用户名不合规');
userNameTip.show();

const passwordTip = new LoginTip('密码不正确');
passwordTip.show();
复制代码

...

这样真是太没有逼格了...

缺点:

  1. 每次使用时需要找到对应的类。
  2. 多次复用时命名不够通用。

所以我们就想到了使用函数进行封装,通过传参及对参数的判断调用不同的基类来实现我们的需求。

比如我们要去超市买海鲜,里面有很多海鲜和它的相关信息,其实是只需要询问售货员就可以解决我们的信息诉求而不用一个个地去看每一个海鲜专柜上面帖的相关信息。

// 帝王蟹基类
const KingCrab = function() {
    this.name = '帝王蟹'
} 

KingCrab.prototype = {
    features: function() {
        console.log('它有八条腿,横着走')
    },
    size: function() {
        console.log('最大能有一只成年猫那么大')
    }
}

// 基围虾基类
const JShrimp = function() {
    this.name = '基围虾'
} 

JShrimp.prototype = {
    features: function() {
        console.log('尾巴蜷曲,头很大')
    },
    size: function() {
        console.log('最大能有成年螃蟹那么大')
    }
}

// 海鲜工厂
const SeafoodFactory = function(name) {
    switch(name) {
        case 'crab'return new Crab();
        case 'shrimp':
           return new Shrimp();
    }
}
复制代码

这样,我想要了解螃蟹相关的信息,只需要使用SeafoodFactory这个海鲜工厂就可以了,例如:

const eatCrab = SeafoodFactory('crab');
console.log(eatCrab.name); // 帝王蟹
console.log(eatCrab.features); // 它有八条腿,横着走
...
复制代码

有时候,一个对象也可以代替许多类。

比如,我们想要建立一批特工人员档案,他们有很多共性比如身手敏捷、熟悉各种枪械等等,也有很多不同点比如身高、性别、特长等。我们就可以这样来做处理:

function createSpecial(height, sex, speciality, num) {
		// 创建一个对象
		const obj = {} || new Object();
		// 拓展其属性和方法
		// 通过传参处理不同点
		obj.height = height;
		obj.sex = sex;
		obj.speciality = speciality;
		// 处理相同点
		obj.action = "敏捷";
		obj.familiarWith = "各种枪械";
		// 当然了,也可以设置各种方法
		obj.personalShow = function() {
			return "此人曾经" +
				num +"次立功" + '...'
		}
		// 返回对象
		return obj;
	}
	const secretService1 = createSpecial('170', '男', '唱歌', 3);
	const secretService2 = createSpecial('188', '女', '跳舞', 6);
	console.log(secretService1.speciality); // 唱歌
	console.log(secretService1.personalShow()); // 此人曾经3次立功...
	console.log(secretService2.speciality); // 跳舞
	console.log(secretService2.personalShow()); // 此人曾经6次立功...
复制代码

在这个基础上,把不同的几个类改造成一个工厂模式也就很简单了。

我们可以抽象出这些类的相同点(参照上面的写法),同时通过函数参数传递不同类的类型在函数体内进行判断并调用不同的逻辑就好啦。

比如我们需要对不同的特工分配不同的作战任务, as the follow,

function divideTask(type, operation) {
        const obj = {};
        // 共同属性或方法
        obj.tasks = operation;
        obj.todo = function(task) {
        	console.log('执行'+task);
        	obj.taskList = [];
        	obj.taskList.push('执行'+task);
        };
        // 通过对type的值进行判断来处理不同的逻辑
        if(type === "一级特工") {
        	obj.todo(obj.tasks[0])
        } else if (type === "二级特工") {
        	obj.todo(obj.tasks[1])
        } else{
        	obj.todo(obj.tasks[2])
        }
        return obj;
	}
	const operation = {0: '执行雷霆扫穴任务', 1: '执行火线救援任务', 2: '执行反恐合围任务'};
	const secretService1 = divideTask('一级特工', operation); // 执行执行雷霆扫穴任务
	const secretService2 = divideTask('二级特工', operation); // 执行执行火线救援任务
	console.log(secretService1.taskList); // ["执行执行雷霆扫穴任务"]
	console.log(secretService2.taskList); // ["执行执行火线救援任务"]
复制代码

总结:本文总共介绍了两种简单工厂创建模式:第一种简单工厂创建模式是通过类实例化对象后创建的,第二种是通过创建中间空对象然后扩展其属性和方法实现的。

区别:第一种方法的基类如果有继承自同一父类,则可以公用父类上的同一方法;而通过寄生方式创建的每一个对象都是一个新的个体,所以不能公用方法(利用了函数内部变量在函数执行完毕之后即销毁这一特性)。具体使用就是仁者见仁,智者见智了。

应该场景:在团队开发项目中我们需要尽量减少全局变量以避免全局覆盖和节省全局空间,而代码复用也是面向对象编程的一条不二准则。所以为了避免在不同需求中重复使用同一类对象,我们可以通过简单工厂模式创建一些对象,可以让这些对象在共用一些资源的同时而又私有一些资源,真的很nice! 不过要注意的是:简单工厂模式仅适合在创建单一对象的时候使用。

觉得这篇文章整理得好、思路清晰的记得给点个赞哈!觉得写得不好的也请给个意见哈,翘首恭候您的佳音!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值