JS 设计模式(2)-- 复习

61 阅读4分钟

JS 设计模式(2)-- 复习

目录

[TOC]

策列模式

策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的用户,策列模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委托给不同的对象进行算法管理

    let startgry = {
        's': salary => salary * 5,
        'a': salary => salary * 4,
        'b': salary => salary * 3,
        'c': salary => salary * 2
    }
    function calBonus(level, salary) {
        // if (level == 'a') {
        //     return salary * 4
        // }
        // if (level == 'b') {
        //     return salary * 3
        // }
        // if (level == 'c') {
        //     return salary * 2
        // }
        return startgry[level](salary)
    }
 
    console.log(calBonus('a', 3000));

该模式主要解决多种算法相似的情况下,使用if...else所带来的复杂和难以维护,他的优点是算法可以自由切换,同时可以避免多重if else 判断 且具有良好的扩展性

代理模式

代理模式,为其他对象提供一种代理,以控制这个对象的访问

代理模式使得代理对象控制具体对象的引用,代理几乎可以是任何对象,文件,资源,内存中的对象,或者是一些难以复杂的东西

class Star {
        play() {
            console.log('演戏');
        }
    }
    class StarProxy {
        constructor() {
            this.superStar = new Star()
        }
        talk(price) {
            if (price >= 10000) {
                this.superStar.play()
            } else {
                throw new Error{ '价格不合适' }
            }
        }
    }

es6的proxy

 let star = {
        name: 'zs',
        workPrice: 10000
    }
    let proxy = new Proxy(star, {
        get(target, key) {
            if (key == 'workPrice') {
                console.log('访问了');
            }
            return target[key]
        },
        set(target, key, value) {
            if (key == 'workPrice') {
                console.log('设置了');
                if (value >= 10000) {
                    console.log('可以合作');
                } else {
                    throw new Error('价格不合适')
                }
            }
        }
    })
    console.log(proxy.workPrice = 10000);

观察者模式

观察者模式包含目标和观察者对象两类对象

一个目标可以有任意数目的与之相依赖的观察者

一旦观察目标的状态发生改变,所有观察者都将得到通知

当一个对象的状态发生改变时,所有依赖它的对象都将得到通知并被自动更新,解决了主体对象与观察者之间功能的耦合,即一个对象状态改变给其他对象通知的问题

  // 被观察目标
    class Subject {
        constructor() {
            this.observer = []
        }
        add(observer) {
            this.observer.push(observer)
        }
        ontify() {
            this.observer.forEach(item => {
                item.update()
            })
        }
        remove(observer) {
            this.observer = this.observer.filter(item => item != observer)
        }
    }
    // 观察者
    class Observer {
        constructor(name) {
            this.name = name
        }
        update() {
            console.log('update', this.name);
        }
    }
    let subject = new Subject()
    let observer1 = new Observer('zs')
    let observer2 = new Observer('ls')
    subject.add(observer1)
    subject.add(observer2)
    subject.ontify()
    subject.remove(observer2)
    subject.ontify()
  • 优势:目标与观察者,功能耦合度降低,专注自身功能逻辑;观察者被动接收更新,时间上解耦,实时接收目标者的更新状态
  • 缺点:观察者虽然实现了对象间依赖关系的低耦合,但却不能对事件进行细分管理,如筛选通知指定主题事件通知

发布订阅模式

观察者和目标要相互知道

发布者和订阅者不用相互知道,通过第三方实现调度,属于经过解耦合的观察者模式

    const PubSub = {
        message: {
 
        },
        // 发布
        publish(type, data) {
            if (!this.message[type]) return
            this.message[type].forEach(item => item(data));
        },
        // 订阅
        subscribe(type, cb) {
            if (!this.message[type]) {
                this.message[type] = [cb]
            } else {
                this.message[type].push(cb)
            }
 
        },
        unsubscribe(type, cb) {
            if (!this.message[type]) return
            if (!cb) {
                this.message[type] && (this.message[type].length = 0)
            } else {
                this.message[type] = this.message[type].filter(item => item !== cb)
            }
        }
 
    }
    function testA(params) {
        console.log('testA', params);
    }
    function testB(params) {
        console.log('testB', params);
    }
    function testC(params) {
        console.log('testC', params);
    }
    PubSub.subscribe('A', testA)
    PubSub.subscribe('A', testC)
    PubSub.subscribe('B', testB)
    PubSub.publish('A', '消息来喽')
    PubSub.unsubscribe('A', testC)
    PubSub.publish('A', '消息来喽')
    PubSub.unsubscribe('A')
    PubSub.publish('A', '消息来喽')

模块模式

模块化模式最初被定义在传统软件工程中为类提供私有和公共封装的一种方法

能够使一个单独的对象拥有公共/私有的方法和变量,从而屏蔽来自全局作用域的特殊部分,这可以减少我们的函数名与页面其他脚本区域内定义的函数名冲突的可能性

    let testModule = (function () {
        let count = 0
        return {
            incrment() {
                return ++count
            },
            decrment() {
                return --count
            }
 
        }
    })()
    console.log(testModule.incrment());
    console.log(testModule.incrment());

es6模块化

 export default {
        name: 'moduleA',
        test() {
            return 'test'
        }
    }
<script type="module">
    import moduleA from './1.js'
    console.log(moduleA);
</script>

module模式使用了闭包封装“私有”状态和组织,它提供了一种包装混合公有/私有方法和变量的方式,防止起泄露至全局作用域,并与别的开发人员接口发生冲突,通过该模式。只需返回一个共有api,而其他一切都维持在私有闭包里