首页 > 其他分享 >day 24设计模式

day 24设计模式

时间:2022-11-02 21:11:53浏览次数:41  
标签:24 console log 处理函数 eventName obj new 设计模式 day

概述:

设计模式是一种固定的解决某个问题的一种方式,不区分语言,常用的设计模式有23种,分为三大类(针对类和对象)

设计模式分类

创建型 (创建对象)单例模式、工厂模式

结构型(将多个小结构变成一个大结构)组合模式 代理模式 装饰器模式 适配器模式

行为型(对应类和对象的行为进行相关处理)观察者模式

设计模式的原则

开闭原则

里氏置换原则

单一原则

依赖倒置原则

接口隔离原则

迪米特原则

工厂模式

根据工厂方法生成对象

function factory(name){
//手动构建对象
var obj = new Object()
//给对象进行属性赋值
obj.name = name
//手动返回对象
return obj
}
//调用工厂生产对象
let obj1 = factory('jack')
let obj2 = factory('tom')

单例模式

  //基础类
        class Instance{
            constructor(){

            }
        }
        //闭包实现
        function closureSingleton(){
            var instance=null
            return function(){
                if(!instance){
                   instance=new Instance()
                }
                return instance
            }

        }
        let  single=closureSingleton()
        let instance1=new single()
        let instance2=new single()
        console.log(instance1==instance2);
        //原型
        function prototypeSingleton(){
            if(!prototypeSingleton.prototype.instance){
                prototypeSingleton.prototype.instance=new Person()
            }
            return prototypeSingleton.prototype.instance
        }
        let instance3=new single()
        let instance4=new single()
        console.log(instance3==instance4);
        //静态属性
        function staticSingleton() {
            if(!staticSingleton.instance){
                staticSingleton.instance=new Person()
            }
            return staticSingleton.instance
        }
        let instance5=new single()
        let instance6=new single()
        console.log(instance5==instance6);
        //全局属性实现
        function globalSingleton() {
            if(!window.instance){
                window.instance=new Person()
            }
            return window.instance
        }
        let instance7=new single()
        let instance8=new single()
        console.log(instance7==instance8);

组合模式(*)

将多个对象的相同方法或者属性组合到一块

 class GOToHome {
            constructor() {
                this.action = () => {
                    console.log('回家');
                }
            }
        }
        class OpenComputer {
            constructor() {
                this.action = () => {
                    console.log('打开电脑');
                }
            }
        }
        class PlayGame {
            constructor() {
                this.action = () => {
                    console.log('玩游戏');
                }
            }
        }
        //将多个方法组合在一起进行调用
        class Combiner {
            constructor() {
                this.list = []
            }
            push(obj) {
                this.list.push(obj)
            }
            excute(fnName, ...arg) {
                this.list.forEach(item => {
                    item[fnName].call(this, ...arg)
                })
            }
        }
        let combiner = new Combiner()
        combiner.push(new GOToHome())
        combiner.push(new OpenComputer())
        combiner.push(new PlayGame())
        combiner.excute('action')

组合模式在vue中的使用

Vue.use(自动执行install)

install

如果在use里面传入的是一个函数 那么他会把这个函数直接当成install 如果传的是对象 他会自动
去找里面的instal方法

模拟实现use和install

class Vue {
constructor() {
this.fnList = []
}
use(obj) {
//如果他是一个函数 那么这个函数直接当成install
if (typeof obj == 'function') {
this.fnList.push(obj)
}
//如果他是对象就找里面的install
if (typeof obj == 'object') {
this.fnList.push(obj.install)
}
//调用执行
this.execute()
}
execute() {
//遍历对应的函数列表
this.fnList.forEach((fn) => {
fn()
})
}
}
var vue = new Vue()
vue.use({
install() {
console.log('你好')
}
})
vue.use({
install() {
console.log('世界')
}
})
vue.use(() => {
console.log('哈哈哈哈')
})

装饰器模式

概述;就是在不影响原本类的基础上,进行功能扩展,又称为包装模式

代码实现

<script>
        //基础类
        class Car{
            constructor(){

            }
            run(){
                console.log('跑');
            }
        }
        //包装类
        class Decorator{
            constructor(car){
                this.car=car
            }
           fly(){
               console.log('飞');
               this.car.run()
           }
        }
        new Decorator(new Car()).fly()
    </script>

在typeScript中有个对应的装饰器修饰 @Decorator

观察者模式 (*)

概述:是前端最常用的模式,又被称为发布者-订阅者模式。核心是一个对应的发布者进行发布,以及对应的有个订阅者(对于发布的内容进行监听),发布者将对应的内容发布,订阅者就会收到信息从而进行对应的处理

观察者模式的核心内容

发布者

订阅者

相关处理

事件也是一个观察者模式

element.addEventListener('事件名',处理函数)
element.removeEventListener('事件名',处理函数)

简单的事件示例

<button>点我</button>
<script>
let btn = document.querySelector('button')
btn.addEventListener('click',handler)
function handler(){
console.log('点击了')
}
</script>

发布者button

订阅者JavaScript

处理 handler

分析这个事件的相关内容
发布者
事件名
处理函数
相关关系
事件名和处理函数的关系 一对多 (一个事件可以有多个处理函数)click:[handler1,handler2]
发布者和事件名的关系
一对多 (一个发布者可以发布多个事件) {事件名:[处理函数]}
根据对应的事件监听机制来模拟观察者
事件监听的过程
事件发布 (有对应的事件名)on
事件执行 (根据对应的事件名执行相关的处理函数) emit
事件取消
(将对应的事件移除)off
代码构建

class ObServer{
constructor(){
//{click:[handler1,handler2],mousemove:[handler1,handler2]}
this.obj = {}
}
//事件发布 事件名 处理函数
on(eventName,handler){
//判断这个eventName是否存在
//如果当前的事件名不存在 给他赋值一个空数组
if(!this.obj[eventName]){
this.obj[eventName] = []
}
//将事件添加进去
this.obj[eventName].push(handler)
}
//事件执行 事件名 参数
emit(eventName,...arg){
//判断这个eventName是否存在
if(!this.obj[eventName]) return
//获取这个事件里面所有的处理函数 执行这些处理函数
//遍历对应的处理函数数组
this.obj[eventName].forEach(handler=>{
//执行对应的处理函数 传入参数
handler.call(this,...arg)
})
}
//事件取消 事件名 处理函数
off(eventName,handler){
//判断这个eventName是否存在
if(!this.obj[eventName]) return
//遍历对应的eventName里面处理函数数组 找到匹配的handler将他删除
this.obj[eventName].forEach((v,i)=>{
if(Object.is(v,handler)){
this.obj[eventName].splice(i,1)
}
})
}
}

注意事项
emit执行他可以传参传给对应的on方法里面处理函数(vue中父传子的实现及bus传值的实现)
off调用一定要emit之前
观察者模式是vue2底层实现

代理模式(*)

概述:

在不改变原本的类的基础上,对于对象进行功能加强,代理模式代理出来的是对象

核心关键词

被代理对象

代理对象

操作内容

代理的实现;在js es7新增了一个Proxy的类 这个类专门用来做代理 

Proxy的使用

  let  obj={
            name:'jack',
            age:18
        }
         //新建代理对象(通过proxy的构造)
        let proxy=new Proxy(obj,{
            get(target,attribute,proxyObj){
               console.log('调用了get');
               if(attribute=='name'){
                return '姓名为'+target[attribute]
               }else if(attribute=='age'){
                return target[attribute]+'岁'

               }
               return target[attribute]
            },
            set(target,attribute,value,proxyObj){
                console.log('调用了set');
                target[attribute]=value 
            },
            defineProperty(target,attribute,descriptor){
             console.log('新的属性定义');
             console.log(descriptor);
            },
            deleteProperty(target,attribute,proxyObj){
                  console.log('删除属性');
                  delete target[attribute]
            }
        })
        console.log(proxy.name);
        console.log(proxy.age);
        proxy.name='你好'
        console.log(proxy.name);
        // delete proxy.name
        console.log((proxy.name))
        console.log(obj);

总结
Proxy是一个es7新增的一个类 他返回的是一个对象
Proxy里面传入被代理对象和对应的处理对象
处理对象包含4个方法(get set defineProperty deleteProperty)
Proxy里面实际操作是被代理对象 (如果在里面操作代理对象会造成栈溢出)
代理对象和被代理对象不是一个对象 但是操作的内容是一个都是被代理对象
Proxy是vue3的底层实现之一

适配器模式
概述
将旧的的内容进行新的适配,在原本的基础上做兼容处理。
常用的业务场景
旧的接口替换新的接口(在不改变原本内容的情况下完成替换)
表单验证 (根据场景切换相关的验证)
示例
家庭用电最大的功率为22v
接入的电压220v
中间就需要继电器(适配口)
代码实现

class phone{
constructor(){
}
fn(){
return 22
}
}
class Adaptive{
constructor(){
}
fn(){
return '220转为'+new Phone().fn()
}
}
//实际使用的是对于的适配的内容
new Adaptive().fn()

 

标签:24,console,log,处理函数,eventName,obj,new,设计模式,day
From: https://www.cnblogs.com/zmfhtml5/p/16852461.html

相关文章