设计模式
设计模式是在软件工程中解决常见问题的经典解决方案。它们是一套被反复使用、多数人知晓、经过分类编目的代码设计经验的总结。设计模式可以帮助程序员提高代码的可重用性、可维护性和可扩展性,进而提高大型软件的开发效率。 简单来说,设计模式可以分为以下几类:
- 创建型模式:这类模式主要关注
对象的创建过程,包括单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式等。 - 结构型模式:这类模式主要关注
类和对象之间的组合,包括适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式等。 - 行为型模式:这类模式主要关注对象之间的
通信,包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、状态模式、中介者模式、备忘录模式、访问者模式等。
前端常见的设计模式有单例模式、观察者模式、装饰器模式等。
- 单例模式确保一个类只有一个实例,并提供一个全局访问点。
- 装饰器模式动态地给一个对象添加一些额外的职责。
- 观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知并自动更新。
观察者模式
观察者设计模式是一种行为型设计模式,定义了对象间的一种一对多的依赖关系,其中一个对象(称为Subject)维护着一系列依赖它的对象(称为Observer),并在状态发生变化时通知这些观察者,所有依赖于它的对象(观察者)通常会被调用它们的某个如update的方法得到通知并自动更新。这种模式通常用于实现分布式事件处理系统,在该系统中,当一个对象(Subject)的状态发生变化时,所有依赖它的对象(Observer)会自动收到通知,接着观察者一般会采取相应动作。
结构
- 主题(Subject) :被观察的对象,维护观察者的列表。
- 观察者(Observers) :观察主题状态变化并作出响应的对象。
- 具体主题(ConcreteSubject) :具体实现了主题接口的类。
- 具体观察者(ConcreteObserver) :具体实现了观察者接口的类,响应主题的变化。
模式涉及的一般接口
addObserver(observer)方法添加观察者,notifyObservers()*方法通知所有观察者状态更新,setState(state)方法改变状态并触发通知。
React中的观察者模式
在现代的 JavaScript 框架(如 React、Vue.js 或 Angular)中,观察者模式通常用于状态管理和组件的响应式更新。例如,在 React 中:
- 状态(State)在 React 组件中充当 Subject。
- 依赖于状态的组件(即根据状态渲染 UI 的组件)充当 Observer。
- 当状态发生变化时(通过用户输入或外部事件触发),React 会自动重新渲染受影响的组件。
parent component
import React, { useState } from 'react';
import Counter from './Counter';
function App() {
// Create a piece of state to store the counter value
const [count, setCount] = useState(0);
// Function to increment the counter
const increment = () => {
setCount(count + 1); // Update state, which triggers a re-render
};
return (
<div>
<h1>React State Example</h1>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
{/* Pass the current count to the Counter component as a prop */}
<Counter count={count} />
</div>
);
}
export default App;
child component
import React from 'react';
function Counter({ count }) {
return (
<div>
<h2>Counter Component</h2>
<p>The current count is: {count}</p>
</div>
);
}
export default Counter;
观察者模式的优缺点
优点
- 解耦:观察者模式最重要的优点就是将主题和观察者的通信过程解耦。主题不需要知道观察者的具体实现,只需要知道它们实现了
update方法,并将自己被观察的状态完全传入给update函数。这使得代码更加简洁和模块化。 - 动态关系:观察者可以在运行时动态地添加或移除。这使得系统更加灵活,便于扩展和调整。
- 自动更新:当主题的状态变化时,所有观察者都会自动得到通知并更新,无需手动跟踪状态变化。
- 促进复用:相同的观察者可以在多个不同的主题之间复用,从而提高了组件的可重用性。
缺点
- 内存泄漏:如果观察者没有正确移除,可能会导致内存泄漏,尤其是在长时间运行的应用程序或单页面应用(SPA)中。问题发生在当观察者对象的引用没有被清除时。
- 性能开销:当观察者的数量非常多时,每次主题状态变化时通知所有观察者会增加性能开销,可能导致性能下降。
- 不可预测的行为:如果多个观察者依赖同一个主题,并且执行复杂的操作,它们之间的交互可能导致不可预测或不一致的行为,尤其是在异步环境下。
- 复杂性:如果没有仔细实现,观察者模式可能会增加系统的复杂性。尤其是在有大量观察者的系统中,跟踪状态变化及其对多个组件的影响可能变得非常困难。
Web开发中的其它使用场景
- 实时更新:观察者模式非常适合实时应用程序,例如股票行情、聊天应用或协同文档编辑。
- 事件处理:像 React、Angular 和 Vue.js 这样的框架内部使用观察者模式的变种来保持 UI 与应用程序状态同步。
- 表单验证:可以通过观察者模式监听表单输入的变化,每当用户输入时,观察者(验证器)会检查输入的有效性。
- WebSocket客户端:WebSocket连接可以充当主题,通知观察者关于实时消息的更新。例如,在聊天应用中,多个 UI 部件会随着新消息的到来而自动更新。
结论
观察者模式在 Web 开发中应用广泛,特别适用于动态的、事件驱动的应用程序。它能够帮助简化复杂的系统,通过解耦组件实现模块化,但在处理大量观察者时,需要特别注意内存管理和性能优化。现代框架如 React 就利用了类似的概念来管理组件状态和响应式更新。