写一个js框架你会用到哪些设计模式

  1. 模块模式 (Module Pattern): 假设我们正在编写一个 JS 应用,需要处理一定量的配置变量。使用模块模式可以把变量隐藏在闭包中,并暴露一个简洁的接口,如下所示:

    var appConfig = (function() {
        var config = {
            apiUrl: 'https://example.com/api',
            apiKey: '123456'
        }
    
        return {
            getApiUrl: function() {
                return config.apiUrl;
            },
            getApiKey: function() {
                return config.apiKey;
            }
        }
    })();
    

    在上面的代码中,我们把 config 对象包裹在闭包中才隐藏了起来,而通过返回的对象,我们可以实现与其它模块互动并读取配置数据。

  2. 工厂模式 (Factory Pattern): 工厂模式可以用于创建多个类似的对象。例如创建一个人的类和创建一个动物的类可以使用如下代码:

    class Person {
        constructor(name, age) {
            this.name = name;
            this.age = age;
        }
    }
    
    class Animal {
        constructor(name, species) {
            this.name = name;
            this.species = species;
        }
    }
    
    class Factory {
        create(type, ...args) {
            switch(type) {
                case 'person':
                    return new Person(...args);
                case 'animal':
                    return new Animal(...args);
                default:
                    throw new Error(`Unsupported type: ${type}`);
            }
        }
    }
    
    const factory = new Factory();
    
    const person = factory.create('person', 'John', 26);
    const animal = factory.create('animal', 'lion', 'mammal');
    

    通过使用工厂模式,我们可以方便地创建多个类似的对象。

  3. 单例模式 (Singleton Pattern): 单例模式可以用于保证全局只存在一个实例。例如,我们可以使用单例模式来管理浏览器窗口:

    const WindowManager = (function() {
        let instance = null;
    
        function WindowManager() {
            if(instance) {
                return instance;
            }
    
            instance = this;
    
            this.windows = [];
        }
    
        WindowManager.prototype.addWindow = function(window) {
            this.windows.push(window);
        }
    
        WindowManager.prototype.removeWindow = function(window) {
            const index = this.windows.indexOf(window);
    
            if(index !== -1) {
                this.windows.splice(index, 1);
            }
        }
    
        return WindowManager;
    })();
    
    const windowManager = new WindowManager();
    
    const window1 = { ... };
    windowManager.addWindow(window1);
    
    const window2 = { ... };
    windowManager.addWindow(window2);
    

    在上面的例子中,我们使用了一个闭包来封装 instance 变量,保证 WindowManager 类只有一个实例,并使用 windowManager 实例来管理浏览器窗口。

  4. 观察者模式 (Observer Pattern): 观察者模式可以用于建立对象间的一对多依赖关系。例如,我们可以使用观察者模式来监控表单输入变化:

    class Subject {
        constructor() {
            this.observers = [];
        }
    
        addObserver(observer) {
            this.observers.push(observer);
        }
    
        removeObserver(observer) {
            const index = this.observers.indexOf(observer);
    
            if(index !== -1) {
                this.observers.splice(index, 1);
            }
        }
    
        notify(value) {
            this.observers.forEach(observer => {
                observer.update(value);
            });
        }
    }
    
    class Observer {
        update(value) {
            console.log(`Input changed: ${value}`);
        }
    }
    
    const inputSubject = new Subject();
    const inputObserver = new Observer();
    
    inputSubject.addObserver(inputObserver);
    
    document.getElementById('input').addEventListener('input', event => {
        const value = event.target.value;
    
        inputSubject.notify(value);
    });
    

    在上面的代码中,我们通过将 Observer 实例添加到 Subject 实例中,当表单输入变化时,Subject 会自动通知 Observer 实例更新。

  5. 适配器模式 (Adapter Pattern): 适配器模式可以用于将不同对象之间的接口转换为兼容的接口。例如,我们可以使用适配器模式将一个类的接口转换为另一个类的接口:

    class LegacyWidget {
        constructor(text) {
            this.text = text;
        }
    
        render() {
            return `<div>${this.text}</div>`;
        }
    }
    
    class NewWidget {
        constructor(text) {
            this.text = text;
        }
    
        draw() {
            return `<div>${this.text}</div>`;
        }
    }
    
    class LegacyWidgetAdapter {
        constructor(widget) {
            this.widget = widget;
        }
    
        draw() {
            return this.widget.render();
        }
    }
    
    const legacyWidget = new LegacyWidget('Hello, World');
    const newWidget = new NewWidget('Goodbye, World');
    
    const legacyWidgetAdapter = new LegacyWidgetAdapter(legacyWidget);
    
    const widgets = [legacyWidgetAdapter, newWidget];
    
    widgets.forEach(widget => {
        console.log(widget.draw());
    });
    

    在上面的例子中,我们通过创建一个适配器 LegacyWidgetAdapter,将 LegacyWidgetrender 方法适配成 NewWidgetdraw 方法,实现对两个不同类的兼容。

  6. 组合模式 (Composite Pattern):组合模式可以用于将对象组合成树形结构,使得用户以一致的方式对待单一对象和对象集合。例如,我们可以使用组合模式来创建一个文件系统:

    class File {
        constructor(name) {
            this.name = name;
        }
    
        getSize() {
            return 10; // Placeholder
        }
    }
    
    class Directory {
        constructor(name) {
            this.files = [];
            this.name = name;
        }
    
        addFile(file) {
            this.files.push(file);
        }
    
        getSize() {
            return this.files.reduce((total, file) => total + file.getSize(), 0);
        }
    }
    
    const file1 = new File('file1.txt');
    const file2 = new File('file2.txt');
    const file3 = new File('file3.txt');
    
    const directory1 = new Directory('directory1');
    directory1.addFile(file1);
    directory1.addFile(file2);
    
    const directory2 = new Directory('directory2');
    directory2.addFile(file3);
    
    const root = new Directory('root');
    root.addFile(directory1);
    root.addFile(directory2);
    
    console.log(`Size of root directory: ${root.getSize()}`);
    

    在上面的例子中,我们使用组合模式将文件和目录组合成树形结构,使得用户可以以一致的方式对待单一文件和文件集合。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值