当前位置: 首页 > article >正文

面试之《前端常见的设计模式》

前端开发中运用多种设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是一些常见的前端设计模式:

创建型模式

1. 单例模式
  • 定义:确保一个类只有一个实例,并提供一个全局访问点。
  • 应用场景:在前端中,像全局状态管理对象、数据库连接对象等通常使用单例模式。例如,在 React 项目中使用 Redux 管理全局状态,Redux 的 store 就是一个单例,整个应用只有一个 store 实例。
  • 示例代码(JavaScript)
class Singleton {
    constructor() {
        if (!Singleton.instance) {
            this.data = [];
            Singleton.instance = this;
        }
        return Singleton.instance;
    }
    addItem(item) {
        this.data.push(item);
    }
    getData() {
        return this.data;
    }
}
const singleton1 = new Singleton();
const singleton2 = new Singleton();
console.log(singleton1 === singleton2); // true
2. 工厂模式
  • 定义:定义一个创建对象的接口,让子类决定实例化哪个类。
  • 应用场景:当创建对象的逻辑比较复杂时,使用工厂模式可以将对象的创建和使用分离。例如,在创建不同类型的弹窗组件时,可以使用工厂模式根据不同的参数创建不同样式和功能的弹窗。
  • 示例代码(JavaScript)
class Button {
    constructor(text) {
        this.text = text;
    }
    render() {
        return `<button>${this.text}</button>`;
    }
}

class Link {
    constructor(text, url) {
        this.text = text;
        this.url = url;
    }
    render() {
        return `<a href="${this.url}">${this.text}</a>`;
    }
}

class ElementFactory {
    createElement(type, ...args) {
        if (type === 'button') {
            return new Button(...args);
        } else if (type === 'link') {
            return new Link(...args);
        }
        return null;
    }
}

const factory = new ElementFactory();
const button = factory.createElement('button', 'Click me');
const link = factory.createElement('link', 'Google', 'https://www.google.com');
console.log(button.render());
console.log(link.render());

结构型模式

1. 装饰器模式
  • 定义:动态地给一个对象添加一些额外的职责。
  • 应用场景:在前端中,常用于给组件添加额外的功能,如添加样式、事件处理等。例如,在 React 中可以使用高阶组件(HOC)来实现装饰器模式,给组件添加日志记录、权限验证等功能。
  • 示例代码(JavaScript)
function logDecorator(component) {
    return class extends React.Component {
        componentDidMount() {
            console.log('Component mounted');
        }
        render() {
            return <component {...this.props} />;
        }
    };
}

class MyComponent extends React.Component {
    render() {
        return <div>My Component</div>;
    }
}

const DecoratedComponent = logDecorator(MyComponent);
2. 代理模式
  • 定义:为其他对象提供一种代理以控制对这个对象的访问。
  • 应用场景:在前端中,常用于处理图片懒加载、数据缓存等。例如,使用代理对象来控制对图片资源的访问,当图片进入可视区域时再加载真实的图片资源。
  • 示例代码(JavaScript)
class Image {
    constructor(src) {
        this.src = src;
        this.loadImage();
    }
    loadImage() {
        console.log(`Loading image from ${this.src}`);
    }
    display() {
        console.log(`Displaying image from ${this.src}`);
    }
}

class ProxyImage {
    constructor(src) {
        this.src = src;
        this.realImage = null;
    }
    display() {
        if (!this.realImage) {
            this.realImage = new Image(this.src);
        }
        this.realImage.display();
    }
}

const proxy = new ProxyImage('https://example.com/image.jpg');
proxy.display();

行为型模式

1. 观察者模式
  • 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。
  • 应用场景:在前端中,常用于实现事件系统、状态管理等。例如,在 Vue.js 中,响应式原理就是基于观察者模式实现的,当数据发生变化时,会自动更新与之绑定的 DOM 元素。
  • 示例代码(JavaScript)
class EventEmitter {
    constructor() {
        this.events = {};
    }
    on(eventName, callback) {
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }
        this.events[eventName].push(callback);
    }
    emit(eventName, ...args) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(callback => callback(...args));
        }
    }
    off(eventName, callback) {
        if (this.events[eventName]) {
            this.events[eventName] = this.events[eventName].filter(cb => cb!== callback);
        }
    }
}

const emitter = new EventEmitter();
const callback = (message) => {
    console.log(`Received message: ${message}`);
};
emitter.on('message', callback);
emitter.emit('message', 'Hello, world!');
emitter.off('message', callback);
emitter.emit('message', 'This message won\'t be received.');
2. 状态模式
  • 定义:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
  • 应用场景:在前端中,常用于实现组件的不同状态切换,如按钮的不同状态(正常、禁用、加载中)。
  • 示例代码(JavaScript)
class ButtonState {
    constructor(button) {
        this.button = button;
    }
    click() {}
    render() {}
}

class NormalState extends ButtonState {
    click() {
        console.log('Button clicked');
    }
    render() {
        return '<button>Normal</button>';
    }
}

class DisabledState extends ButtonState {
    click() {
        console.log('Button is disabled');
    }
    render() {
        return '<button disabled>Disabled</button>';
    }
}

class Button {
    constructor() {
        this.state = new NormalState(this);
    }
    setState(state) {
        this.state = state;
    }
    click() {
        this.state.click();
    }
    render() {
        return this.state.render();
    }
}

const button = new Button();
button.click();
button.setState(new DisabledState(button));
button.click();

以上只是前端开发中常见的一些设计模式,实际应用中可以根据具体需求选择合适的设计模式来优化代码。


http://www.kler.cn/a/586116.html

相关文章:

  • spring boot程序启动时读取覆盖配置文件中的变量
  • 蓝桥杯备考:红黑树容器map应用---英语作文
  • React19源码系列之FiberRoot节点和Fiber节点
  • springboot validation 校验字段是否为空
  • Java开发之微服务架构设计:Spring Cloud Alibaba核心组
  • 探索HTML5 Canvas:创造动态与交互性网页内容的强大工具
  • 从前端视角理解消息队列:核心问题与实战指南
  • 基于Transformer的医学文本分类:从BERT到BioBERT
  • 3.14-1列表
  • C++【类和对象】(超详细!!!)
  • iPhone 17系列新机模上手,横向矩阵镜头+超薄机身,清新白色设计
  • Flask-Login完整使用案例
  • iOS 模块化架构设计:主流方案与实现详解
  • SpringCloud 学习笔记1(Spring概述、工程搭建、注册中心、负载均衡、 SpringCloud LoadBalancer)
  • 大数据如何赋能零售行业进行产品创新
  • 大语言模型微调和大语言模型应用的区别?
  • 基于SpringBoot + Vue 的房屋租赁系统
  • Spring Boot 读取 ZooKeeper (ZK) 属性的总结指南
  • 基于javaweb的SpringBoot杂物商城系统设计与实现(源码+文档+部署讲解)
  • ES6 字符串和正则表达式