设计模式
2020-04-26 16:57:02 2 举报
AI智能生成
设计模式
作者其他创作
大纲/内容
1. 课程介绍
1. 3年工作经验,面试必考设计能力<br>2. 成为项目技术负责人,设计能力是必要基础<br>3. 从写好代码,到做好设计,设计模式是必经之路
知识点
面向对象
1. ES6 class语法<br>2. 三要素<br>3. UML类图
设计原则
1. 为何设计<br>2. 5大设计原则<br>3. 从设计到模式
设计模式
1. 分优先级讲解<br>2. 结合核心技术<br>3. 结合框架引用
综合示例
1.设计方案<br>2. 代码演示<br>3. 设计模式对应
课程安排
面向对象
1. 使用webpack 和 babel 搭建ES6编译环境<br>2. ES6 class面向对象语法<br>3. 面向对象三要素:继承 封装 多态
设计原则
1. 《LINUX/UNIX设计哲学》,以及代码演示<br>2. 5大设计原则分析和理解,以及代码演示<br>3. "设计模式"——>从 "设计"到“模式”
设计模式
1. 概述:创建型、结构型、行为型<br>2. 常用设计模式,详细讲解,结合经典实用场景<br>3. 非常用设计模式,理解概念,示例演示<br>4. 有主有次,掌握重点
综合示例
1. 用jQuery实现一个简单的购物车<br>2. 设计分析,话UML类图<br>3. 代码演示<br>4. 总结实用的7种设计模式
讲授方式
1. 先基础后实践,先“设计”后“模式”<br>2. 重点、常用的设计模式,配合经典使用场景<br>3. 结合示例,演示设计模式如何使用<br>4. 用JS的方式讲解面向对象和设计模式
课程收获
1. 面向对象思想,UML类图<br>2. 5大设计原则,23种设计模式<br>3. 能应对前端面试中想关的面试题<br>4. 提升个人设计能力
学习基础
1. 了解面向对象,能熟练使用jQuery或类似工具库<br>2. 有ES6语法基础,用过nodejs和npm<br>3. 了解vue和react(至少看过文档,做过demo)
重点提示
1. 本课程讲解设计模式,不是实战项目也不是源码分析<br>2. 23种设计模式不是都常用,分清主次<br>3. 设计模式在JS和Java中的讲解方式有区别<br>4. 不适合刚入门编程的同学,参考上文的学习前提
2. 面向对象
搭建开发环境
什么是面向对象
1. 概念<br>2. 三要素:继承 封装 多态<br>3. JS应用举例<br>4. 面向对象的意义
面向对象三要素
1. 继承,子类继承父类<br>2. 封装,数据的权限和保密<br>3. 多态,同一接口不同实现
继承
继承可将公共方法抽离出来,提高复用,减少冗余
封装
1. public 完全开放<br>2. private对自己开放<br>3. protected对子类开放
1. 减少耦合,不该外露的不外露<br>2. 利于数据、接口的权限管理<br>3. ES6目前不支持,一般认为_开头的属性时private
多态
1. 同一个接口,不同表现<br>2. JS应用极少<br>3. 需要结合java等语言的接口、重写、重载等功能
1. 保持子类的开放性和灵活性<br>2. 面向接口编程<br>3. (JS中使用极少,了解即可)
JS应用举例
1. jQuery是一个class<br>2. $('p')是jQuery的一个实例
为何使用面向对象?
1. 程序执行:顺序、判断、循环——结构化<br>2. 面向对象——数据结构化<br>3. 对于计算机,结构化的才是最简单的<br>4. 编程应该 简单&抽象
面向对象的意义:
数据结构化
UML类图
1. UML:Unified Modeling Language统一建模语言<br>2. 类图,UML包含很多种图,和本课程相关的是类图<br>3. 关系,主要讲解泛化和关联<br>4. 演示,代码合类图结合
画图工具
1. MS Office visio<br>2. https://www.processon.com
类图
怎么画
类图:包含类名,属性,方法
+ public<br>-private
示例
关系
1. 泛化,表示继承<br>2. 关联,表示引用<br>
示例
泛化使用空箭头,A和B 继承了People<br>引用使用实心箭头,People引用了House
总结
1. 类图,属性、方法<br>2. 关系,泛化、关联
3. 设计原则
何为设计?<br>五大设计原则<br>从设计到模式<br>介绍23种设计模式<br>
何为设计
1. 即按照哪一种思路或者标准来实现功能<br>2. 功能相同,可以有不同设计方案来实现<br>3. 伴随着需求增加,设计的作用才能体现出来
《UNIX/LINUX设计哲学》
1. 准则1:小即是美<br>2. 准则2:让每个程序只做好一件事<br>3. 准则3:快速建立原型<br>4. 准则4:舍弃高效而取可移植性<br>5. 准则4:采用纯文本来存储数据<br>6. 准则6:充分利用软件的杠杆效应(软件复用)<br>7. 准则7:使用shell脚本来提高杠杆效应和可移植性 <br>8. 准则8:避免强制性的用户界面<br>9. 准则9:让每个程序都称为过滤器
小准则<br>1. 允许用户定制环境<br>2. 尽量使用操作系统内核小而轻量化<br>3. 使用小写字母并尽量简洁<br>4. 沉默是金<br>5. 各部分之和大于整体<br>6. 寻求90%的解决方案
演示
准则9:过滤器
ls | grep *.json 从ls的结果中过滤json后缀的文件
小准则:沉默是金
不要改变返回值类型<br><br>比如一个程序,期望输出数字,如果给出提示比如“没有文件”,这就改变了返回值类型
SOLID五大设计原则
五大原则
S-单一职责原则 single<br>
1. 一个程序只做好一件事<br>2. 如果功能过于复杂就拆分开,每个部分保持独立<br>
S-O-开放封闭原则 open close<br>
1. 对扩展开放,对修改封闭<br>2. 增加需求时,扩展新代码,而非修改已有代码<br>3. 这是软件设计的终极目标
L-李氏置换原则<br>
1. 子类能覆盖父类<br>2. 父类能出现的地方子类就能出现<br>3. JS中使用较少(弱类型&继承使用较少)
I-接口独立原则 interface <br>
1. 保持接口的单一独立,避免出现“胖接口”<br>2. JS中没有接口(typescript例外),使用较少<br>3. 类似于单一职责原则,这里更关注接口
D-依赖导致原则 dependence
1. 面向接口编程,依赖于抽象而不依赖于具体<br>2. 使用方只关注接口而不关注具体类的实现<br>3. JS中使用较少(没有接口&弱类型)
总结
1. S O 体现较多,详细介绍<br>2. L I D体现较少,但是要了解其用意
示例
单一职责原则:每个then中的逻辑值做好一件事<br>开放封闭原则:如果新增需求,扩展then
从设计到模式
设计<br>模式<br>分开<br>“从设计到模式”
23种设计模式
创建型<br>
1. 工厂模式(工厂方法模式,抽象工厂模式,建造者模式)<br>2. 单例模式<br>3. 原型模式
组合型<br>
1. 适配器模式<br>2. 装饰器模式<br>3. 代理模式<br>4. 外观模式<br>5. 桥接模式<br>6. 组合模式<br>7. 享元模式
行为型
1. 策略模式<br>2. 模板方法模式<br>3. 观察者模式<br>4. 迭代器模式<br>5. 职责链模式<br>6. 命令模式<br>7. 备忘录模式<br>8. 状态模式<br>9. 访问器模式<br>10. 中介者模式<br>11. 解释器模式
如何学习设计模式
1. 明白每个设计的道理和用意<br>2. 通过经典应用体会它的真正使用场景<br>3. 自己编码时多思考,尽量模仿
面试真题
题目1
打车时,可以打专车或者快车。任何车都有车牌号和名称<br>不同车价格不同,快车每公里1元,专车每公里2元<br>行程开始时,显示车辆信息<br>行程结束时,显示打车金额(假定行程就5公里)<br><br>要求:<br>1. 画出UML类图<br>2. 用ES6语法写出该示例
UML
代码
把车和行程分开
题目2
某停车场,分3层,每层100车位<br>每个车位都能监控到车辆的驶入和离开<br>车辆进入前,显示每层的空余车位数量<br>车辆进入时,摄像头可识别车牌号和时间<br>车辆出来时,出口显示器显示车牌号和停车时长<br><br>要求:<br>画图UML类图<br>
UML
4. 工厂模式
介绍
1. 将new操作单独封装<br>2. 遇到new时,就要考虑是否该使用工厂模式<br>
示例
1. 你去购买汉堡,直接点餐。取餐,不会自己亲手做<br>2. 商店要“封装”做汉堡的工作,做好直接给买者
UML
传统UML
简化后的UML
代码演示
Creator把Product构造函数封装起来,返回一个Product的实例<br>
工厂模式<br>使用场景
1. jQuery-$('div')<br>
$('div')和new $('div')有何区别?<br>
$('div')是工厂模式<br>$就是一个工厂<br><br>new $('div')不是工厂模式<br>
使用new $('div')的弊端<br>
第一,书写麻烦,jQuery的链式操作将才能为噩梦<br>第二,一旦jQuery名字变化,将是灾难性的
示例
jQuery题外话<br>1. 聊一聊阅读经典lib源码的意义(学习源码如何设计)<br>2. 聊一聊创新和拿来主义()
React.createElement<br>
JSX
JSX 转化
从源码可以看出它是工厂模式
vue异步组件
设计原则验证
1. 构造函数和创建者分离<br>2. 符合开放封闭原则
5. 单例模式
介绍
1. 系统中被唯一使用<br>2. 一个类只有一个实例<br>
示例
登录框<br>购物车
登录框、购物车只能有一个
UML
说明
1. 单例模式需要用到java的特性(private)<br>2. ES6 中没有(typescript)<br>3. 只能用java代码来演示UML图的内容
代码演示
java代码演示
构造函数私有化
子主题
JS代码演示
不能使用new SingleObject(),验证可只obj1和obj3不相等
//结果,obj1和obj3不相等
单例模式使用场景
jQuery只有一个$
思想和单例模式是一样的
模拟登录框
其他
购物车(和登陆框类似)<br><br>vuex和redux中的store(模块A和模块B获取的store必须是相同的,所以是单例)
设计原则验证
1. 符合单一职责原则,只实例化唯一的对象<br>2. 没法具体体现开放封闭原则,但是绝对不违反开放封闭原则
6. 适配器模式
介绍
1. 旧接口格式和使用者不兼容<br>2. 中间加一个适配转换接口
UML
传统UML类图
简化类图
代码演示
场景
封装接口
vue computed
设计原则验证
1. 将旧接口和使用者进行分离<br>2. 符合开放封闭原则
7. 装饰器模式
介绍
1. 为对象添加新功能<br>2. 不改变其原有的结构和功能
比如手机壳、指环等,增加新功能,不影响手机原有的功能
UML
传统UML类图
简化UML
代码演示
结果
装饰器模式,<br>保留了原来的功能,并增加新的功能
场景
ES7装饰器
装饰类
装饰类的原理
原理
demo
@mixins
装饰方法
@readonly<br>
// 结果,修改p.name 后依旧输出老方法<br>在严格模式下( 'use strict' ),会报错
@log
core-decorators
1. 第三方开源lib<br>2. 提供常用的装饰器<br>3. https://github.com/jayphelps/core-decorators<br> https://www.npmjs.com/package/core-decorators
@readonly
@deprecate
设计原则验证
1. 将现有对象和装饰器进行分离,两者独立存在<br>2. 符合开放封闭原则
8. 代理模式
介绍
1. 使用者无权访问目标对象<br>2. 中间加代理,通过代理做授权和控制
示例
1. 科学上网,访问github.com<br>2. 明星经纪人
UML
传统UML类图
简化的UML类图
代码演示
场景
网页事件代理
jQuery $.proxy
左图等价于右图
子主题
ES6 Proxy
设计原则验证
1. 代理类和目标类分离,隔离开目标类和使用者<br>2. 符合开放封闭原则
区别
代理模式 vs 适配器模式
1. 适配器模式:提供一个不同的接口(如不同版本的插头)<br>2. 代理模式:提供一模一样的接口
代理模式 vs 装饰器模式
1. 装饰器模式:扩展功能,原有功能不变且可直接使用<br>2. 代理模式:显示原有功能,但它是经过限制或者阉割之后的
9. 外观模式
介绍
1. 为子系统中的一组接口提供了一个高层接口<br>2. 使用者使用这个高层接口
UML
场景
设计原则验证
1. 不符合单一职责原则和开放封闭原则,因此谨慎使用,不可滥用
10. 观察者模式
介绍
1. 发布 & 订阅<br>2. 一对n,可以一对一,也可以一对多
示例
点咖啡,点好之后坐等被叫<br>
UML
传统UML类图
简化UML类图
Subject可以绑定多个观察者observers<br>Subject中有state, 可以获取状态getState 可以设置状态setState<br>当状态设置完之后,nofifyAllObservers() 触发所有观察者的update方法
Observer观察者<br>当它被触发时,会执行update()<br>观察者定义好以后,它就等待被触发
代码演示
每个subject的state改变时,<br>都会触发这个subject所有的观察者的update方法
场景
网页事件绑定
按钮点击也是一种状态变化<br>当按钮被点击时,状态发生变化,触发所有的回调函数
Promise
promise状态变化后,比如图片加载成功resove()<br>then()中所有的函数都要被触发
jQuery callbacks
nodejs自定义事件
EventEmitter
继承
Stream
readline
其他场景
nodejs 中:处理http请求;多进程通讯
HTTP
多进程通讯
vue 和 React 组件生命周期触发
React组件
vue watch
设计原则验证
1. 主题和观察者分离,不是主动触发而是被动监听,两者解耦<br>2. 符合开放封闭原则
11. 迭代器模式
介绍
1. 顺序访问一个集合<br>2. 使用者无需知道集合的内部结构(封装)<br>
示例
三种有序集合的遍历
对三种不同的有序集合,需要使用不同的遍历方法
使用jQuey生成迭代器
$(data)<br>把不同的有序集合,都使用jQuery把它变成jQuery对象
顺序遍历有序集合<br>使用者不必知道集合的内部结构
UML
传统UML类图
简化UML类图
getIterator()生成迭代器
Iterator<br>next()遍历<br>hasNext()判断是否还有下一个,遍历是否结束
代码演示
场景
jQuery each
ES6 Iterator
ES6 Iterator为何存在?
1. ES6语法中,有序集合的数据类型已经有很多<br>2. Array Map Set String TypedArray arguments NodeList<br>3. 需要有一个统一的遍历接口来遍历所有数据类型<br>4. (注意,object不是有序集合,可以用Map代替)
ES6 Iterator 是什么?
1. Array Map Set String TypedArray arguments NodeList<br> 以上数据类型,都有[Symbol.iterator]属性<br>2. 属性值是函数,执行函数返回一个迭代器<br>3. 这个迭代器就有 next 方法可顺序迭代子元素<br>4. 可运行Array.prototype[Symbol.iterator]来测试
用done来判断遍历是否完成
示例
for of
for of遍历的对象,必须是带有遍历器特性的对象, 即data[Symbol.iterator] 有值
ES6 Iterator 与 Generator
Iterator
1. Iterator 的价值不限于上述几个类型的遍历<br>2. 还有Generator 函数的使用<br>3. 即只要返回的数据符合Iterator接口的要求<br>4. 即可使用 Iterator 语法,这就是迭代器模式
Generator
示例
设计原则验证
1. 迭代器对象和目标对象分离<br>2. 迭代器将使用者和目标对象隔离开<br>3. 符合开放封闭原则
12. 状态模式
介绍
1. 一个对象有状态变化<br>2. 每次状态变化都会触发一个逻辑<br>3. 不能总是用 if ... else 来控制
示例
交通信号灯不同颜色的变化
UML
传统UML类图
传统UML类图
红绿灯<br>代码演示
把状态单独抽象出来<br>把主体也单独抽象出来,<br><br>主体对象可以获取和设置状态<br>状态对象可以切换状态
场景
有限状态机
1. 有限个状态、以及在这些状态之间的变化<br>2. 如交通信号灯<br>3. 使用开源lib: javascript-state-machine<br>4. https://github.com/jakesgordon/javascript-state-machine<br>
使用
methods的方法名 和 transitions中的name<br>要符合图示的命名规则
代码演示
写一个简单的Promise
1. 回顾Promise的语法<br>2. 分析:Promise就是一个有限状态机<br>3. 写代码
回顾Promise语法
Promise就是有限状态机
1. Promise 三种状态:pending fullfilled rejected<br>2. 状态转化:pending->fullfilled 或者pending->rejected<br>3. 状态转化一旦完成,不可逆
实现代码
四个要点<br>
1. 由new Promise可知<br> Promise是一个class
2. Promise 初始化时,要接收一个参数,这个参数是一个函数<br> 所以constructor中接收一个函数
3. 传入的这个函数,有两个参数<br> 成功时执行resolve 失败时执行reject
4. 由result.then(function(){})可知<br> new Promise生成的实例具有then()方法<br> 所以要在Promise构造函数中实现then()<br><br> then()接收两个参数,第一个是resolve时触发,第二个是reject触发
代码演示
模型
实现Promise
测试
设计原则验证
1. 将状态对象和主题对象分离,状态的变化逻辑单独处理<br>2. 符合开放封闭原则
13. 其他设计模式
优先级划分依据
1. 不常用<br>2. 对应不到经典的应用场景
讲解方式
1. 代码演示,说明该设计模式的目的和用意<br>2. 不再画UML类图(此前画过N次了)
有哪些设计模式
创建型
原型模式<br>
概念
1. clone 自己,生成一个新对象<br>2. java 默认有 clone接口,不用自己实现<br>
Object.create
对比 JS 中的原型 prototype
1. prototype 可以理解为 ES6 class 的一种底层原理<br>2. 而class是实现面向对象的基础,并不是服务于某个模式<br>3. 若干年后 ES6 全面普及,大家可能会忽略掉 prototype<br>4. 但是Object.create 缺会长久存在
结构型
桥接模式<br>
概念
1. 用于把抽象化与实现化解耦<br>2. 使得二者可以独立变化<br>3. (未找到JS中的经典应用)
演示
扩展性比较差
改进
设计原则验证
1. 抽象和实现分离,解耦<br>2. 符合开放封闭原则
组合模式<br>
概念
1. 生成树形结构,表示'整体-部分'关系<br>2. 让整体和部分都具有一致的操作方式<br>
演示
1. JS 经典应用中,未找到这么复杂的数据类型<br>2. 虚拟 DOM 中的vnode 是这种形式,但数据类型简单<br>3. (用 JS 实现一个菜单,不算经典应用,与业务相关)
1. 整体和单个节点的操作是一致的<br>2. 整体和单个节点的数据结构也保持一致
设计原则验证
1. 将整体和单个节点的操作抽象出来<br>2. 符合开放封闭原则
享元模式
概念
1. 共享内存(主要考虑内存,而非效率)<br>2. 相同的数据,共享使用<br>3. (JS 中未找到经典应用场景)
演示
设计原则验证
1. 将相同的部分抽象出来<br>2. 符合开放封闭原则
行为型
策略模式<br>
概念
1. 不同策略分开处理<br>2. 避免出现大量 if...else 或者swich...case<br>3. (JS 中未找到经典应用场景)
演示
会出现大量的if...else
改进
设计原则验证
1. 不同策略,分开处理,而不是混在一起<br>2. 符合开放封闭原则
模板方法模式<br>
职责链模式<br>
概念
1. 一步操作可能分为多个职责角色来完成<br>2. 把这些角色都分开,然后用一个链串起来<br>3. 将发起者和各个处理者进行隔离
演示
应用场景
JS 中的链式操作
1. 职责链模式和业务结合较多, JS 中能联想到链式操作<br>2. jQuery 的链式操作 Promise.then 的链式操作
设计原则验证
1. 发起者于各个处理者进行隔离<br>2. 符合开放封闭原则
命令模式<br>
概念
1. 执行命令时,发布者和执行者分开<br>2. 中间加入命令对象,作为中转站
演示
应用场景
JS 中的应用
网页富文本编辑器操作,浏览器封装了一个命令对象<br>document.execCommand('bold')<br>document.execCommand('undo')
设计原则验证
1. 命令对象与执行对象分开,解耦<br>2. 符合开放封闭原则
备忘录模式<br>
概念
1. 随时记录一个对象的状态变化<br>2. 随时可以恢复之前的某个状态(如撤销功能)<br>3. 未找到 JS 中经典应用,除了一些工具(如编辑器)
演示
设计原则验证
1. 状态对象与使用者分开,解耦<br>2. 符合开放封闭原则
中介者模式<br>
概念
买卖房子,买家和卖家通过中介联系
演示
设计原则验证
1. 将各关联对象通过中介者隔离<br>2. 符合开放封闭原则
访问者模式<br>
1. 将数据操作和数据结构进行分离<br>2. 使用场景不多
解释器模式
1. 描述语言语法如何定义,如何解释和编译<br>2. 用于专业场景,babel sass less
关于面试和日常使用
关于面试
能说出课程重点讲解的设计模式即可<br>
日常使用
重点讲解的设计模式,要强制自己模仿、掌握<br>非常用的设计模式,视业务场景选择性使用
14. 综合应用
介绍 & 演示
1. 使用jQuery 做一个模拟购物车的示例<br>2. 包括:显示购物车列表、加入购物车、从购物车删除
用到哪些设计模式
工厂模式 <br>单例模式<br>装饰器模式<br>观察者模式<br>状态模式<br>模板方法模式<br>代理模式
说明:很难用一个示例演示完所有设计模式
UML类图
准备环境
代理
代理
使用http-server -p <br>开启一个本地服务
http-server -p <br>
解决跨域问题
代码演示
src/demo
总结用到的设计模式
工厂模式
使用jQuery的$('xxx')
创建商品
单例模式
购物车<br>export getCart()函数<br>这个函数返回一个购物车单例
装饰器模式
打点统计 @log
观察者模式
网页事件 click
Promise
状态模式
添加购物车<br>从购物车删除
模板方法模式
渲染有统一的方法,内部包含了各模块渲染<br>init() {<br> 。。。<br> }<br>
代理模式
打折商品信息处理
15. 课程总结
0 条评论
下一页