Vue双向数据绑定,用到哪些设计模式?

经历过前端面试的同学,大部分被问过:Vue双向数据绑定原理。

回答:双向数据绑定的原理,vue2中采用“数据劫持”结合“发布者-订阅者”模式的方式,通过“Object.defineProperty()”方法来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。vue3 则通过Proxy代理实现。

这个回答相信你早已烂熟于心,如果你只是记着这段话没真正理解其中意思,面试官结合设计模式换一个问法,很多同学就会翻车呢。

vue双向数据绑定原理图

01设计模式

作为工程师的我们,对于设计模式还是有必要掌握的,什么是设计模式呢?

设计模式是软件工程中用于解决特定问题的一系列最佳实践。设计模式不是完整的设计解决方案,而是在特定上下文中解决特定问题的模板。

简单点说,设计模式是以前的程序员在开发解决特定问题时,积累的一套优雅的代码写法。

设计模式可以分为三大类:创建型模式、结构型模式和行为型模式。

创建型模式(Creational Patterns)

创建型模式关注对象的创建过程,隐藏创建逻辑,并且通过使用对象的接口来控制对象的创建。

典型的有单例模式、工厂模式、原型模式

结构型模式(Structural Patterns)

结构型模式关注对象的组合,通过组合简单对象形成复杂的结构。

典型的有代理模式、装饰器模式、适配器模式、组合模式

行为型模式(Behavioral Patterns)

行为型模式专注于对象间的通信,即对象如何相互协作以完成复杂的任务。

典型的有策略模式、观察者模式、迭代器模式

设计模式是软件开发中的一种重要工具,它们帮助开发者编写可维护、可扩展且容易理解的代码。每种设计模式都有其特定的应用场景和优缺点,选择合适的模式可以提高软件设计的质量。

02、观察者模式

阅读vue源码不难发现,观察者模式的身影。观察者模式(Observer Pattern)是一种行为设计模式,它研究的是对象间的关系。它定义了对象间的一种一对多的依赖关系,使得当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。在JavaScript中,观察者模式可以用于实现事件监听和通知机制。

以下是使用JavaScript实现观察者模式的一个简单示例:

1. 定义观察者接口

class Observer {
update() {}
}

2. 定义具体观察者

class ConcreteObserver extends Observer {
    constructor(name) {
        super();
        this.name = name;
    }

    update(state) {
        console.log(`${this.name} received state: ${state}`);
    }
}

3. 定义主题接口

class Subject {
    constructor() {
        this._observers = [];
    }

    attach(observer) {
        this._observers.push(observer);
    }

    detach(observer) {
        this._observers = this._observers.filter(obs => obs !== observer);
    }

    notify(state) {
        this._observers.forEach(observer => observer.update(state));
    }
}

4. 定义具体主题

class ConcreteSubject extends Subject {
    constructor(state) {
        super();
        this._state = state;
    }

    get state() {
        return this._state;
    }

    set state(value) {
        this._state = value;
        this.notify(this._state);
    }
}

5. 使用观察者模式

// 创建具体主题
const subject = new ConcreteSubject();

// 创建具体观察者
const observerA = new ConcreteObserver('Observer A');
const observerB = new ConcreteObserver('Observer B');

// 注册观察者
subject.attach(observerA);
subject.attach(observerB);

// 改变主题状态,观察者将收到通知
subject.state = 'active';

// 注销一个观察者
subject.detach(observerA);

// 再次改变主题状态,只有Observer B会收到通知
subject.state = 'inactive';

在这个示例中,ConcreteSubject 类代表被观察的主题,它持有一个状态并在状态改变时通知所有注册的观察者。ConcreteObserver 类代表观察者,它们实现了 Observer 接口的 update 方法来响应状态变化。

JavaScript 中的观察者模式通常与事件监听机制紧密相关,实际上,JavaScript 的 EventTarget 和 addEventListener、removeEventListener、dispatchEvent 等方法已经提供了观察者模式的实现。在实际开发中,你可能会使用这些内置方法来实现事件驱动的交互,而不是从头开始实现观察者模式。

03、发布订阅者模式

Vue中也使用发布订阅者模式实现双向数据绑定原理,发布订阅者模式(Publish-Subscribe Pattern),又称为观察者模式的一种变体,它允许对象(订阅者)订阅消息或事件,并在这些消息或事件发生时得到通知。这种模式解耦了事件的发送者和接收者,使得发送者不必知道谁是接收者,接收者也不必知道谁是发送者。

在发布订阅者模式中,有三个主要的组件:

  1. 主题(Topic):一个消息的分类,订阅者可以订阅一个或多个主题。

  2. 发布者(Publisher):创建消息并发布到特定主题的对象。

  3. 订阅者(Subscriber):对特定主题感兴趣的对象,当主题有消息发布时,订阅者会收到通知。

以下是使用JavaScript实现发布订阅者模式的一个示例:

1. 创建发布订阅者系统

class EventSystem {
    constructor() {
        this.events = {};
    }

    subscribe(topic, callback) {
        if (!this.events[topic]) {
            this.events[topic] = [];
        }
        this.events[topic].push(callback);
    }

    unsubscribe(topic, callback) {
        if (!this.events[topic]) {
            return;
        }
        this.events[topic] = this.events[topic].filter(cb => cb !== callback);
    }

    publish(topic, data) {
        if (this.events[topic]) {
            this.events[topic].forEach(callback => callback(data));
        }
    }
}

2. 使用发布订阅者系统

const eventSystem = new EventSystem();

// 定义订阅者
function subscriberA(data) {
    console.log('Subscriber A received:', data);
}

function subscriberB(data) {
    console.log('Subscriber B received:', data);
}

// 订阅主题
eventSystem.subscribe('message', subscriberA);
eventSystem.subscribe('message', subscriberB);

// 发布消息
eventSystem.publish('message', 'Hello, subscribers!');

// 取消订阅
eventSystem.unsubscribe('message', subscriberA);

// 再次发布消息,只有subscriberB会收到
eventSystem.publish('message', 'Hello again, remaining subscribers!');

在这个示例中,EventSystem 类提供了订阅、取消订阅和发布消息的功能。订阅者通过 subscribe 方法注册到特定的主题,当 publish 方法被调用时,所有订阅了该主题的订阅者都会收到消息。

发布订阅者模式非常适合于实现松耦合的系统,其中组件之间的交互不需要直接依赖对方。这种模式在事件驱动的架构中非常常见,例如在Web开发中的事件监听、WebSocket通信、消息队列等场景。

04、发布订阅者和观察者模式区别

观察者模式是由具体目标调度,比如当事件触发,就会去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的。

发布/订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。

05、总结

文章通过"vue双向数据绑定原理"面试题,引入设计模式相关知识。详细了设计模式中的观察者模式和其变体发布订阅模式,并分析了两者区别。

目前整理的精典设计模式有23种,分别应用于不同场景,解决特定问题,在开发中有意识积累、运行,能提高代码质量,在代码可读性,可维护性方面更上层楼。

  • 57
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

missterzy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值