设计模式的分类
一、创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
二、结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
三、行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
一、工厂模式
定义
封装一个类,通过这个类实例化我们的对象
例子
下面这个例子当中,我们有一个产品类,一个工厂类。 产品类当中,有产品的属性以及方法。 工厂类当中,存在生产产品的方法。 我们实例化一个工厂,然后通过这个工厂来生产产品。
class Product{
constructor(name){
this.name = name
}
init(){
alert(‘init’)
}
fun1(){
alert(‘fun1’)
}
}
class Creator{
create(name){
return new Product(name)
}
}
let creator = new Creator();
let p = creator.create(‘p1’)
常见场景
1.jQuery中的$('div')方法
如果用原来的new方法去创建jQuery对象,就无法进行链式调用
采用工厂模式,让jQuery可以形成链式调用
class jQuery{
constructor(selector){
....
}
append(node){...}
addClass(name){...}
html(data){...}
}
window.$ = function(selector){
return new jQuery(selector)
}
2.React.createElement
React创建虚拟dom的实例
React.createElement("div",null,
React.createElement("img",{ src: "aatar.png", className: "profile" }),
React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
);
class Vnode(tag, attrs, children){...}
React.createElement = function (tag, attrs, children) {
return new Vnode(tag, attrs, children)
}
设计原则
1.构造函数和创建者分离
2.符合开放封闭原则
二、单例模式
定义
一个类只有一个实例
例子
需要用到private特性,外部无法new这个对象。js无法实现,但是现在可以通过ts实现。
class SingleObject{
// 将构造函数私有化,外部就无法直接实例化
private constructor(){
}
// 对象唯一实例,且不允许外部更改
private instance:SingleObject = null;
public getInstance(){
if(this.instance === null) {
// 只创造一次实例
return new SingleObject();
}
return this.instance;
}
// 实例上的方法
public login = (username:string, password:string) => {
// ...
}
}
常见场景
1.jQuery只有一个$
if(window.jQuery !== null) {
return window.jQuery
} else {
// 初始化
}
2.模态框
我们平常所使用的模态框一般一个功能用的都是同一个。对模态框一般采用的都是显示、隐藏,而非重复的创造、销毁。
3.vuex和redux中的store
整个vue当中使用的store对象都是同一个,如果各个页面用的store对象不同,也就无法实现数据同步互相通信了。
设计原则
1.符合单一职责原则,只实例化唯一的对象
2.没法具体开放封闭原则,但是绝对不违反开放封闭原则
三、适配器模式
定义
旧接口的格式和我现在的使用场景不兼容或者不适用,通过一个中间转换来转换接口。
例子
下面这个例子只是简单的示范
class OldProduct{
public a: string;
public sum: number;
constructor(a: string, sum: number){
this.a = a;
this.sum = sum;
}
}
class Adaptor {
adapte(a:string,num1:number,num2:number){
return new OldProduct(a,num1+num2);
}
}
let adapte = new Adaptor();
let newProduct = adapte.adapte('a',1,2);
常见场景
1.二次封装组件
在react和vue开发过程当中经常会出现组件当前虽然在当前场景可以使用,但是使用起来很复杂,逻辑和当前业务不适配。所以,这个时候就可以对组件二次封装,将组件的配置项做一个改造,这样一来,就可以简化我们的开发,提高开发效率。
- vue computed
computed其实使用到的就是适配器模式的思想,原先的数据可能不适用当前场景,通过computed,来进行一个转化,形成我们所想要的样子。
设计原则
1.将旧接口和使用者进行分离
2.符合开放封闭原则
四、装饰器模式
定义
在不改变原有对象的结构和功能的基础上,为对象添加新功能
例子
class Circle {
draw() {
console.log('画一个圆形')
}
}
class Decorator {
public circle
constructor(circle) {
this.circle = circle
}
draw() {
this.circle.draw()
}
// 添加一个边框变红的功能
setRedBorder(){
console.log('设置红色边框')
}
}
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()
dec.setRedBorder()
常见场景
- ES7的装饰器语法(mobx开发中常用)
@testDec
class Demo{...}
function testDec(target) {
target.isDec = true;
}
alert(Demo.isDec);
- 组件二次封装添加新功能
一般开发当中,如果当前组件不满足我们的需求,就可以通过二次封装,新增新的功能。一般还会结合适配器模式,对配置项进行适配改造。
3.core-decorators
一个第三方开源lib,提供常用的装饰器
设计原则
1.将现有对象和装饰器进行分离,两者独立存在
2.符合开放封闭原则