Javascript 设计模式系统讲解与应用 笔记
Javascript 设计模式系统讲解与应用
第1章 课程介绍
面试敲门砖、进阶垫脚石、设计有模式、代码更合理
第2章 面向对象
2-1 搭建开发环境
基于 webpack webpack-cli 搭建。
2-2 什么是面向对象
2-3 面向对象-继承
2-4 面向对象-封装
2-5 面向对象-多态
2-6 面向对象-应用举例
2-7 面向对象-总结
2-8 UML类图1-介绍
2-9 UML类图2-关系
2-10 总结
第3章 设计原则
3-1 设计原则-介绍
3-2 设计原则-何为设计
3-3 设计原则-5大原则
S O L I D 五大设计原则
- S - 单一责任原则
- O - 开放封闭原则
- L - 里氏替换原则
- I - 接口独立原则
- D - 依赖倒置原则
单一责任原则
- 一个程序只做好一件事
- 如果功能过于负责就拆分,每个部分保持独立
开放封闭原则
- 对扩张开发,对修改封闭
- 增加需求时,扩张新代码,而非修改已有代码
- 这个是软件设计的终极目标
里氏替换原则
- 子类能覆盖父类
- 父类能出现的地方子类就能出现
- JS中使用较少(弱类型&继承使用较少)
接口独立原则
- 保持接口的单一独立,避免出现 “胖接口”
- JS中没有接口(typescript例外),使用较少
- 类似于单一职责原则,这里更关注接口
依赖倒置原则
- 面向解扣子编程,依赖于抽象而不依赖于具体
- 使用方只关注接口而不关注具体类的实现
- JS中使用较少
设计原则总结
- S O 体现较多,详细介绍
- LID 体现较少,但是要了解其用意
用Promise来说明 S-O
function loadImg(src) {
var promise = new Promise(function(resolve, reject) {
var img = document.createElement('img')
img.onload = function () {
resolve(img)
}
img.onerror = function () {
reject('图片加载失败')
}
img.src = src
})
return promise
}
var src = 'https://www.imooc.com/static/img/index/logo.png'
var result = loadImg(src)
result.then(function (img) {
console.log('img.width', img.width)
return img
}).then(function (img) {
console.log('img.height', img.height)
}).catch(function (err) {
console.error(err)
})
- 单一职责原则:每个 then 中的逻辑只做好一件事
- 开放封闭原则:如果新增需求,扩展then
- 对扩展开发,对修改封闭
3-4 用promise演示
就是3-3的代码
3-5 设计模式简介
从设计到模式
体会什么是设计?设计是设计,模式是模式,两者是分离的。
该如何学习设计模式?
- 明白每个设计的道理和用意
- 通过经典应用体会它的真正使用场景
- 自己编码时多思考,尽量魔模仿
3-6 23种设计模式介绍
其实设计模式大致分为三种类型:
- 创建型
- 组合型
- 行为型
这23种设计模式分别分散在这三种类型中。
创建型
- 工厂模式(工厂方法模式、抽象工厂模式、建造者模式)
* 工厂模式是讲怎么面向对象、怎么创建对象、怎么生成 - 单例模式
* 单例模式是讲如果这个系统中只有一个指定对象,那么出现第二个时,该怎么办 - 原型模式
* 原型模式是讲如何通过一个现有的对象,用拷贝的方式来生成另一个新的对象
结构型
- 适配器模式
- 装饰器模式
- 代理模式
- 外观模式
- 桥接模式
- 组合模式
- 享元模式
行为型
- 策略模式
- 模板方法模式
- ★观察者模式★
- 迭代器模式
- 职责链模式
- 命令模式
- 备忘录模式
- ★状态模式★
- 访问者模式
- 中介模式
- 解释器模式
如何讲解设计模式
- 介绍和举例(生活中易理解的示例)
- 画UML类图写demo代码
- 结合经典应用场景,讲解该设计模式如何被使用
3-7 面试真题1
- 打车时,可以打专车或者快车。任何车都有车牌号和名称
* 解析:需设计公共父类(车牌号和名称),父类下又有两子类(专车和快车)) - 不同车价格不同,快车每公里1元,专车每公里2元
* 解析:子类里有不同的价格 - 行程开始时,显示车辆信息
* 行车和车有关系,但和专车还是快车没关系。所以我们需要依赖抽象编程,所以行程只和车有关系,不和具体哪种车有关,也就是说无论什么车都有行车信息
* 所以我们需要再建一个"行程"的类,这个类引用车的某个属性,我们可以通过这个属性得到车的信息(车牌号、名称、单价) - 行程结束时,显示打车金额(假定行程就5公里)
* “金额”属于行程。买了一万辆车丢着是没有行程金额的
UML类图
class Car {
constructor(number, name) {
this.number = number
this.name = name
}
}
class Kuaiche extends Car {
constructor(number, name) {
super(number, name)
this.Price = 1
}
}
class Zhuanche extends Car {
constructor(number, name) {
super(number, name)
this.Price = 2
}
}
class Trip {
constructor(car) {
this.car = car
}
start() {
console.log(`行程开始,名称:${this.car.name},车牌号:${this.car.Price}`)
}
end() {
console.log(`行程结束,价格:${this.car.Price * 5}`)
}
}
let car = new Kuaiche('101', '捷达')
let trip = new Trip(car)
trip.start()
trip.end()
3-8 面试真题2
- 某停车场,分3层,每层100车位
* 解析:三个类,分别是停车场、每层、车位,三个class - 每个车位都能监控到车辆的驶入和离开
* 解析:我们要给车位这个类定义一个方法或者属性来监控车辆驶入和离开,这个监控的方法要改变车位这个类的一个状态,车位空不空 - 车辆进入前,显示每层的空余车位数量
* 解析:车辆进入前肯定面对的是停车场这个类,所以这个信息要在停车场这个类中释放出来,所以我们加一个方法,动态计算显示每一层(每一层都是一个类的实例)空车位,所以层这个类里还得加显示空车位的方法,最终由停车场这个类累加后显示 - 车辆进入时,摄像头可以识别车牌号和时间
* 解析:还得加摄像头的class,这个class有方法能识别出车牌号和记录驶入时间,也就是说摄像头这个类,输入的是车的实例,输出车牌号和时间,这个车牌号和时间要让停车场那个类里去存,所以停车场这个类还得加车辆列表的属性 - 车辆出来时,出口显示器显示车牌号和停车时长
* 解析:还得加显示器的类,通过显示器拿到车牌号和记录的驶入时间,然后用当前时间减去这个事件就拿到了停车时长
TODO: 补代码
3-9 总结
第4章 工厂模式
原理
- 将
new
操作单独封装 - 遇到
new
时,就要考虑是否该使用工厂模式
示例
- 你去购买汉堡,直接点餐、取餐,不会自己亲手做
- 商店要 “封装” 做汉堡的工作,做好直接给顾客
场景
jQuery - $('div')
React.createElement
vue异步组件
React.createElement
React.createElement使用工厂模式的好处:如果我们不用 createElement 封装 new VNode(tag,attrs, children)
,在对生成VNode示例时我们还是让用户去验证各个属性参数,显示不合理,而且用了工厂模式后用户根本不关系内部构造函数怎么变化。
vue异步组件
Vue异步加载组件完成后创建组件的模式
使用工厂模式把工厂内部构造函数与用户隔离
设计原则验证
- 构造函数和创建者分离
- 符合开放封闭原则
第5章 单例模式
- 系统中仅被唯一使用的
- 一个类只有一个实例
示例
- 登录框
- 购物车
- vuex和redux中的store
jQuery
永远只有一个
设计 原则 验证
- 符合单一职责原则,只实例化唯一的对象
- 没法具体开放封闭原则,但是绝对不违反开放封闭原则
第6章 适配器模式
- 就接口格式和使用者不兼容
- 中间加一个适配器接口
场景
- 封装旧接口
- Vue的computed
设计原则验证
- 将就借口和使用者进行分离
- 符合开放封闭原则