作为一个前端新人,学习了设计模式以后,希望能从源头上,用浅显易懂的语言来解释它。当然不一定是正确的,只是我个人对设计模式的一点浅显理解。
创建型设计模式
创建型设计模式:故名思意,这些模式都是用来创建实例对象的。
单例模式:首先我们需要理解什么是单例。
单:指的是一个。
例:指的是创建的实例。
单例:指的是创建的总是同一个实例。也就是使用类创建的实例始终是相同的。
我们先看下面的一段代码:
class Person{
constructor(){}
}
let p1 = new Person();
let p2 = new Person();
console.log(p1===p2) //false
上面这段代码,定义了一个Person类,通过这个类创建了两个实例,我们可以看到最终这两个实例是不相等的。也就是说,通过同一个类得到的实例不是同一个(这本就是理所应当),但是如果我们想始终得到的是同一个实例,那么这就是**单例模式**。那么应该如何实现单例模式了:
想要实现单例模式,我们需要注意两点:
- 需要使用return。使用new的时候如果没有手动设置return,那么会默认返回this。但是,我们这里要使得每次返回的实例相同,也就是需要手动控制创建的对象,因此这里需要使用return。
- 我们需要每次return的是同一个对象。也就是说实际上在第一次实例的时候,需要把这个实例保存起来。再下一个实例的时候,直接return这个保存的实例。因此,这里需要用到闭包了。
代码实现如下:
(function(){
let instance = null;
return class{
constructor(){
if(!instance){
//第一次创建实例,那么需要把实例保存
instance = this;
}else{
return instance;
}
}
}
})()
let p3= new Person();
let p4 = new Person();
console.log(p3===p4) //true
从上面的代码中,我们可以看到在闭包中,使用instance变量来保存创建的实例,每次返回的都是第一次创建的实例。这样的话就实现了无论创建多少次,创建的都是同一个实例,这就是单例模式。
工厂模式
对于工厂来说,我们的印象可能是里面具有各种各样的模具,根据你想要的产品的模型,生产你需要的产品。比如说你请工厂帮你加工一个产品,你只需要告诉工厂你这个产品的结构,工厂就会有对应的模型帮你生产,你不需要去关心它具体是怎么加工的。同样工厂模式也是这样,(工厂模式也是创建型设计模式,用于创建实例对象的)你不需要自己去找对应的类来创建实例,你只需要告诉工厂类你要创建什么实例,他就会返回你需要的实例对象。
工厂模式根据抽象程度的不同,分为三种:
1. 简单工厂模式
2. 工厂方法模式
3. 抽象工厂模式
简单工厂模式
定义:定义一个工厂类,通过工厂函数,根据传入的参数不同,返回不同的实例。看下面的代码:
//学生类
class Student{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
//老师类
class Teacher{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
//警察类
class Policeman{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
根据类创建对象
const s1 = new Student('王小一',24);
const t1 = new Teacher('李一老师',39);
const p1= new Policeman('张一警官',40);
我们可以看到,上面代码中定义了三个类,学生类,老师类和警察类。而且它们具有相同的属性和方法。当我们需要创建学生实例时,我们调用学生类。当我们需要创建老师实例时,我们调用老师类,当我们需要创建警察实例,我们调用警察类。假设我们有更多的人物类,它们具有相同的功能,那么当我们需要创建实例的时候,我们同样需要调用相对应的类。事实上,这些类实现的都是相同的功能,那么我们可不可以把所有的创建这些人物实例都通过一个类来实现了。我们尝试将代码修改为如下:
//学生类
class Student{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
//老师类
class Teacher{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
//警察类
class Policeman{
constructor(name,age){
this.name = name;
this.age = age;
}
showName(){
console.log(this.name)
}
}
//工厂类
class Factory{
let obj = null;
//工厂函数
constructor(role,name,age){
switch(role){
case 'student':
obj = new Student(name,age);
break;
case 'teacher':
obj = new Teacher(name,age);
break;
case 'policeman':
obj = new Policeman(name,age);
break;
}
}
return obj;
}
const s2 = new Factory('student','王小二',25);
const t2 = new Factory('teacher','李二老师',39);
const p2 = new Factory('policeman','张二警官',40);
从上面的代码中,我们可以看到我们同样定义了学生类,老师类,警察类这三个类,但是我们创建实例时通过Factory这个类,不再通过相对应的人物类了。这个Factory类就是工厂类,我们观察工厂类的实现,发现里面是一个工厂函数(这里直接使用了constructor,也可以自己定义工厂函数),通过传递给工厂函数的参数不同,返回不同的实例。这就是简单工厂模式。
简单工厂模式总结:
实现:从上面的代码中我们可以知道,所谓简单工厂模式就是一个工厂