设计模式
基础内容
数据结构
计算机网络(网络七层)
操作系统(linux)
计算机原理 (冯诺依曼)
设计模式
概述:用来设计对应类和对象的(建立类和对象的模型的)。不区分语言(主要是思想)。主要设计模式有23种。
主要分为三类
创建型: 用来创建类和对象的(5种)
结构型:将类和对象的结构里面几个小的结构合并为一个大的结构(7种)
行为型: 控制对应的类与对象的行为 (11种)
单例模式
饿汉模式 (访问就返回对象)
懒汉模式 (用的时候才返回对象)
概述:
单例模式指代的是生成出来对象永远只有一个实例
实现过程
构建一个函数返回一个对象实例
用一个声明一次变量来控制这个对象实例的生成
如果这个变量里面已经有了一个对象 直接返回 如果没有生成 生成给变量存起来
闭包实现
function single(){ let obj //标识 return function(){ if(!obj){ //判断是否为undefined obj = new Object() } return obj } } let singleObj = single() let obj1 = singleObj() let obj2 = singleObj() console.log(obj1===obj2)//true
原型实现
function singlePrototype(){ if(!Object.prototype.instance){ Object.prototype.instance = new Object() } return Object.prototype.instance } let obj1 = singlePrototype() let obj2 = singlePrototype() console.log(obj1===obj2) //true
static实现
function singleStatic(){ if(!Object.instance){ Object.instance = new Object() } return Object.instance } let obj1 = singleStatic() let obj2 = singleStatic() console.log(obj1===obj2)
全局变量实现 (有问题的 对应的非浏览器它的global(全局对象)不是window)
function singleWindow(){ if(!window.instance){ window.instance = new Object() } return window.instance } let obj1 = singleWindow() let obj2 = singleWindow() console.log(obj1===obj2)
工厂模式
工厂模式生产对象的,以一个工厂方法来生产对应的对象。
工厂方法实现步骤
手动构建对象
手动给对象设置属性
手动返回对象
function factory(name){ // 先创建一个对象 var obj = new Object() // 给对象设置属性 obj.name = name // 再返回这个对象 return obj } //调用 var Person = factory('jack')
组合模式 *
将对应多个相同名字方法 放在一个地方统一调用
class SayHello{ constructor(){ } say(){ console.log('hello') } } class SayHi{ constructor(){ } say(){ console.log('hi') } } class SayBay{ constructor(){ } say(){ console.log('baybay') } }
以上的三个类 分别都具备一个名为say的方法 如果需要调用的话 那么是一个个的对象进行调用而不能
统一调用,如果我需要他统一调用,这个时候我们就可以使用组合模式。
class Combiner{ constructor(){ //容器来保存对应的对象 this.objs = [] } push(obj){ //添加对象 this.objs.push(obj) } excute(fnName){ //执行对应的方法 this.objs.forEach(item=>{ item[fnName]() }) } } //新建组合模式对象 let combiner = new Combiner() //传入对应统一调用的对象 combiner.push(new SayHello()) combiner.push(new SayHi()) combiner.push(new SayBay()) //执行对应的方法 combiner.excute('say')
组合模式在vue中的使用
use 和 install
vue.use()为注册全局插件所用,接收函数或者一个包含install属性的对象为参数,如果参数带有install
就执行install, 如果没有就直接将参数当install执行, 第一个参数始终为vue对象, 注册过的插件不会重新注册
观察者模式(vue2的底层)*
观察者模式(obServer)他又被称为发布-订阅者模式,消息模式等。
观察者示例
来占座 ---- 没有位置 ---- 等有位置(班主任会告诉你什么时候有位置)---- 班主任告诉你有位置以后 ----过来了(处理)
流程相关内容
发布者 ---- 任务发布者
观察的人 --- 班主任
处理 --- 过来了
最基础的观察者模式(事件)
element.addEventListener('事件名',处理函数) //监听 element.removeEventListener('事件名',处理函数) //取消监听
相关的操作
事件监听
处理函数执行(js引擎)
取消事件监听
根据上述内容我们可以总结出对应的观察者具备对应的三个方法(发布事件 执行处理函数 取消事件)
观察者模式代码书写
class ObServer{ constructor(){ //事件和对应的处理函数存储的容器 this.arg = {} //click:[fn,fn1] } on(){//发布事件 } emit(){//执行处理函数 } off(){//取消事件 } }
class ObServer { constructor() { this.arg = {} //{click:[fn,fn1]} } on(eventName, handler) { //发布事件 事件名 处理函数 if (!this.arg[eventName]) { //没有这个事件 this.arg[eventName] = [] //初始化里面为空数组 } this.arg[eventName].push(handler) //将对应的函数追加 } emit(eventName, params) { //执行处理函数 if (!this.arg[eventName]){ return } //会将里面的处理函数都执行 //遍历对应的处理函数数组 this.arg[eventName].forEach(fn => { //将参数传入执行 fn.call(this, params) }) } off(eventName, handler) { //取消事件 if (!this.arg[eventName]) { return } //将这个对应的fn删除 if (this.arg[eventName].length == 1) { delete this.arg[eventName] } else { let i this.arg[eventName].forEach((item, index) => { if (Object.is(item, handler)) { i = index } }) this.arg[eventName].splice(i, 1) } } }
在观察者emit方法传入参数 传到对应的on里面的处理函数 vue里面子传父的实现
代理模式 *
代理模式利用一个代理对象来处理当前对象事情
示例
老板 ---- 执行秘书(老板的代理)
叫员工开会 ----- 执行秘书去执行老板的操作
es7新增一个类 Proxy 他就是用于代理的,他是vue3的底层实现
Proxy构造函数
new Proxy(目标对象,handler处理对象)
对应的处理对象有4大方法
get属性 获取对应的代理对象的值调用
set属性 设置代理对象的值调用
deleteProperty 删除代理对象的属性调用
has属性 在遍历的时候调用
//目标对象 let target = {name:'张三',age:18,say(){ console.log('hello'); }} //利用proxy产生代理对象 let proxy = new Proxy(target,{ get(target,property,proxy){ //表示目标对象 表示属性名 表示代理对象 console.log('get调用了'); //访问值的时候 if(property =='name'){ return '我的名字是'+target[property] } if(property =='age'){ return '我的年纪是'+target[property]+'岁' } }, set(target,property,value){ //设置值的时候 进行相关操作 console.log(property); console.log(value); target[property] = value }, deleteProperty(target,property,proxy){ //删除属性的时候 console.log('delete调用了'); delete target[property] }, has(target,property){ //in的时候调用 必须返回boolean 强制转换为boolean类型 console.log('has调用了'); console.log(property); return property in target }, apply(target,property){ //函数调用触发 console.log('apply调用了'); } }) //读取代理对象的属性的时候 会自动调用get方法 他的值是get方法返回的值 console.log(proxy.age); //调用get proxy.name = 'jack' //调用set console.log(proxy); delete proxy.name //调用deleteProperty console.log('name' in proxy); //某个东西是否在某个东西里面返回boolean console.log(proxy.say); //代理只第一层
apply对应的方法
function sum(a, b) { return a + b; } const handler = { apply: function (target, thisArg, argumentsList) { //目标对象 当前this 参数数组 console.log('apply调用了'); // expected output: "Calculate sum: 1,2" return target(argumentsList[0], argumentsList[1]) * 10; } }; const proxy1 = new Proxy(sum, handler); console.log(sum(1, 2)); // expected output: 3 console.log(proxy1(1, 2)); // expected output: 30
装饰器模式
在不改变原本对象的情况下进行功能添加
流程
毛坯对象
传入对应的毛坯对象给对应的装饰对象
返回一个精装对象
代码
//原本类 class Car{ constructor(){ } run(){ console.log('车在跑') } } //增强的类 class Decorater{ constructor(car){ this.car = car } run(){ console.log('我边吃饭边开车') this.car.run() } } new Decorater(new Car()).run()
es7新增一个装饰器 其实就是装饰器模式的封装
适配器模式
将对应的一个原本不适配变成适配的。
示例
我有个手机 支持充电5v
我家里的直流电为220v
这个需要一个适配器
代码
let phone = { fn(){ retrun '5v' } } class Target{ constructor(){ } fn(){ let v = phone.fn() return '220转换为'+v } } new Target().fn()
接口处理(老版接口处理为新版本接口)