JS常见的设计模式

单例模式

点击查看代码
<script>
        // 单例模式 => 自始至终都只能创建一个对象 让对象唯一存在
        let Wife = (function(){
            class Person{
                constructor(name){
                    this.name = name
                }
            }
            let instance = null
            function getInstance(name){
                // 获取实例的方法
                if(!instance) instance = new Person(name)
                return instance
            }

            // 返回创建实例函数
            return getInstance
        })()

        // 单例模式
        const w1 = Wife("冰冰")
        const w2 = Wife("菲菲")
        console.log(w1); //冰冰
        console.log(w2); //冰冰
        console.log(w1 === w2); //true

    </script>
使用单例模式实现一个简易版的vuex3
<body>
    <button onclick="fn1()">++</button>
    <button onclick="fn2()">--</button>
    <p></p>
    <script>
        // 使用单例模式实现一个简易版的vuex3
        let Utils = (function(){
            // 存储数据的
            let state = {
                count:1
            }
            // 操作数据
            function mutation(payload){
                // 如果payload => increment 我们就让state.count++
                switch(payload){
                    case "increment":
                        state.count++
                        break
                    case "decrement":
                        state.count--
                        break
                }
                // 如果payload => decrement 我们就让state.count--
            }
            // 将数据返回到外部
            function getState(){
                return state   //返回一个对象
            }
            return { //返回两个函数构成的对象
                mutation,
                getState
            }
        })()
        console.log(Utils === Utils);
        // 获取仓库里面的数据源
        function fn(){
            const p = document.querySelector("p")
            // 获取数据源
            p.innerHTML = Utils.getState().count
        }
        fn()

        // 点击++ 让仓库里面的数据++
        function fn1(){
            // 让仓库里面的count++
            Utils.mutation("increment")
            // 渲染到页面
            fn()
        }
        // 点击-- 让仓库里面的数据--
        function fn2(){
            // 让仓库里面的count--
            Utils.mutation("decrement")
            // 渲染到页面
            fn()
        }
    </script>
</body>

作用:确保一个类只有一个实例对象,让对象唯一存在

应用场景:在需要共享资源或管理全局状态的情况下,如数据库连接池、线程池、全局配置等

组合模式

点击查看代码
<script>
        // 组合模式 => 将拥有相同功能的实例对象存储到一个队列当中 一起执行
        class haha{
            // 如果我们没有写constructor的时候 那么在ES6的类当中 存储在一个默认的没有参数的constructor
            today(){
                console.log("开心,哈哈哈哈哈");
            }
        }
        class heihei{
            today(){
                console.log("开心,嘿嘿嘿嘿嘿");
            }
        }
        class xixi{
            today(){
                console.log("开心,嘻嘻嘻嘻嘻");
            }
        }
        class Comb{
            constructor(){
                this._message = [] //存储多个拥有相同功能的实例对象
            }
            add(instance){
                // 每执行一次add函数 那么就往message盒子里面放入一个实例对象
                this._message.push(instance)
            }
            execute(){
                this._message.forEach(item=>{
                    item.today()
                })
            }
        }

        const ha = new haha() 
        const hei = new heihei()
        const xi = new xixi()
        const comb = new Comb()
        comb.add(ha)
        comb.add(hei)
        comb.add(xi)
        // 批量执行
        c.execute()
    </script>

参考:详解组合模式

作用: 将拥有相同功能的实例对象存储到一个队列当中,一起执行

应用场景:客户端可以忽略组合对象与单个对象的差异;优化处理树形结构、文件目录、菜单、导航

策略模式

点击查看代码
<script>
        // 将一组数据结构(算法)封装起来,对外暴露一个统计的结构(增删改查)
        let Util = (function(){
            //定义一组折扣方案
            let calcType = {
                "80%": price => price *= 0.8,
                "70%": price => price *= 0.7
            }
            //实现折扣
            function inner(type,price){
                //如果没有这种折扣方案,那么报错
                if(!calcType[type]) throw new Error("没有这种折扣方案!")
                //如果有这种折扣方案
                // calcType[type] => 就是一个函数 price => price *= 0.7
                return calcType[type](price)
            }

            //显示所有的折扣方案
            inner.show = () =>{
                return calcType
            }
            //添加一种折扣方案
            inner.add = (type,fn) =>{
                calcType[type] = fn
            }
            //删除一种折扣方案
            inner.remove = (type) =>{
                if(!calcType[type]) throw new Error("没有这种折扣方案")
                delete calcType[type]
            }
            return inner;
        })()
        //添加一种折扣方案
        Util.add("-50",price => price -= 50)
        //删除一种折扣方案
        Util.remove("80%")
        // 显示所有的折扣方案
        console.log(Util.show());

        // console.log(Util("-50",1000));
        // console.log(Util("80%",1000));
 </script>

作用:将一些相似的算法都封装成起来然后暴露给外部使用,使得这些算法可以独立于客户端变化

应用场景:在需要根据不同的策略来完成特定任务的情况下,如排序算法、支付方式选择等

观察者模式

点击查看代码
 <script>
        //定义观察者
        class Observer{
            constructor(){
                //$message => 指的就是消息盒子
                this.$message = {}
            }
            //订阅消息 => 往消息盒子里面添加自定义事件
            $on(type,fn){
                if(this.$message[type]){//第一次往消息盒子里面添加自定义事件
                    this.$message[type].push(fn)
                }else{
                    this.$message[type] = [fn]
                }
            }
            //取消订阅 => 将消息盒子里面对应的事件函数给删除掉
            $off(type, fn) {
                // 1. 先判断消息盒子里面是否存在事件类型
                if (!this.$message[type]) throw new Error("请先订阅消息!")
                // 2. 遍历消息盒子里面对应事件类型的函数
                const arr = this.$message[type];
                for (let i = 0; i < arr.length; i++) {
                    // 3. 如果事件函数中存在着传入进来的事件
                    //     那么就删除这个事件
                    if (arr[i] === fn) {
                        arr.splice(i, 1)
                    }
                }
            }
            //清除订阅 => 将消息盒子里面的事件类型给删除
            $clear(type){
                //判断消息盒子里面是否存在事件类型
                if(!this.$message[type]) throw new Error("请先订阅消息!")
                //清除订阅
                delete this.$message[type]
            }
        }
        const o = new Observer()
        function fn1(){
            console.log("我是一个函数1");
        }
        function fn2(){
            console.log("我是一个函数2");
        }
        //订阅消息
        o.$on('shop',fn1)
        o.$on('shop',fn2)
        //取消订阅
        o.$off("shop", fn1)
        //清除订阅
        o.$clear('shop')
        console.log(o);
    </script>

作用:定义对象间的一种一对多依赖关系,当一个对象的状态发生变化时,它的所有依赖对象都会收到通知并自动更新。

应用场景:在需要实时更新或同步信息的情况下,如用户界面中的事件处理、消息订阅等

工厂模式

作用:一种用来创建对象的设计模式
应用场景:需要批量生产同种类的对象的时候

posted @   饼MIN  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示