JavaScript 面向对象之工厂模式
工厂模式的诞生场景
假设我要教 A 同学前端技术,经过几个月的教学,把他带上路了,A 是一名前端开发者了;
然后过几个月又有一个 B 同学,通过 axihe.com 找到我,让我教他前端技术,经过几个月的教学,把他带上路了,B 是一名前端开发者了;
随着时间的推移,假设越来越多的人找我学习前端,这个时候,我会发现前端技能其实要学的都差不多,每个人要学习的大致路线和技能都差不多,我没有必要一对一的进行教学,然后我会录制一套教程放在 Bilibili 上供大家观看,所有同学找我学习的时候,我把教程给他,他自己学习就好;
假设有 100 个同学找我学前端,我把教程给他们看,经过几个月之后,这 100 个人就都带上路了,也都是前端开发者了;
什么是工厂模式
上面这种按照特定的逻辑生成对象的方式就属于工厂模式
工厂模式的创建
工厂模式是软件工程领域一种广为人知的设计模式,考虑到在 ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装特定接口的对象,
工厂模式:说白了就是一种函数类型;
function anbangEdu (name) {
if (!name) {
throw '没找到学员姓名!不准学!滚!'
}
// 培训时长6个月
let duration = 6;
// 培训技能 HTML/CSS/JS/Vue/React
let skills = ['HTML', 'CSS', 'JavaScript', 'Vue', 'React', 'Angular'];
// 实现案例
let examples = [
'用电话键盘上的0和1,编写一个Windows系统',
'徒手制造原子弹,并成功发射到火星'
]
// 开始都会把学员当做同一个起跑线
// 这里无论使用字面量创建对象还是构造函数都可以的,
// 很多资料里介绍构造的这种属于工厂模式,其实不是的,工厂模式并不是某一种写法,而是一种模式
// var student = new Object();
let student = {
name: name.toString(),
frontend_skills: [],
frontend_examples: [],
is_has_frontend_skill: false,
skills_for_work: null
};
for (let index = 1, len = duration; index < len; index++) {
let skill = skills[index - 1];
student.frontend_skills.push(skill);
switch (skill) {
case 'JavaScript':
// 学到JS的时候,做案例【用电话键盘上的0和1,编写一个Windows系统】
student.frontend_examples.push(examples[0]);
break;
case 'React':
// 学到React的时候,做案例【徒手制造原子弹,并成功发射到火星】
student.frontend_examples.push(examples[1]);
break;
default:
break;
}
}
// 学生还是那个学生,但是经过培训班的毒打,技能已经有增加了。
student.is_has_frontend_skill = true;
student.skills_for_work = () => {
return `前端工作需要的技能,${name} 都掌握了!`
}
return student;
}
let trump = anbangEdu('trump');
console.log(trump);
console.log(trump.skills_for_work());
let pujing = anbangEdu('pujing');
console.log(pujing);
console.log(pujing.skills_for_work());
// obama偷偷的来学,没有告诉我他的名字,所以我给拒绝掉了
let obama = anbangEdu();
函数 anbangEdu
能够根据接受的参数来构建一个包含所有必要信息的对象。可以无数次地调用这个函数,
工厂模式的擅长领域(优点)
工厂模式解决了创建多个相似对象的问题;
- 批量生产数据
- 把实现同一件事情的相同的代码放到一个函数中,以后如果在想实现这个功能,不需要从新的编写这些代码来了,只需要执行当前的函数即可
- “函数的封装” –>“高内聚低耦合”:
- 减少页面中的冗余代码,提高代码的重复利用率;
- 工厂模式的优点就是函数模式的特点
工厂模式的缺点;
工厂模式虽然解决了重复创建相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型), 也就是某个对象属于什么类。