1. 单例模式 (Singleton)
特点:确保一个类只有一个实例,并提供全局访问点。
用途:常用于全局状态管理、配置管理等。
class Singleton {
constructor(name) {
if (Singleton.instance) return Singleton.instance; // 如果已有实例,返回该实例
this.name = name;
Singleton.instance = this; // 保存实例
}
getName() {
return this.name;
}
}
// 测试
const instance1 = new Singleton("First Instance");
const instance2 = new Singleton("Second Instance");
console.log(instance1 === instance2); // true
console.log(instance2.getName()); // "First Instance"
2. 工厂模式 (Factory)
特点:通过工厂方法动态创建不同类的实例,而无需明确指定具体类。
用途:常用于根据条件生成对象(如不同按钮、弹窗等)。
class Button {
render() {
console.log("Rendering a button");
}
}
class Input {
render() {
console.log("Rendering an input field");
}
}
class ComponentFactory {
static createComponent(type) {
switch (type) {
case "button":
return new Button();
case "input":
return new Input();
default:
throw new Error("Unknown component type");
}
}
}
// 测试
const button = ComponentFactory.createComponent("button");
button.render(); // Rendering a button
const input = ComponentFactory.createComponent("input");
input.render(); // Rendering an input field
3. 观察者模式 (Observer)
特点:定义对象间的一种一对多依赖关系,当一个对象改变时,自动通知其依赖者。
用途:常用于事件系统(如 DOM 事件、Vue 的响应式系统)。
class Subject {
constructor() {
this.observers = []; // 存储观察者
}
subscribe(observer) {
this.observers.push(observer); // 添加观察者
}
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer); // 移除观察者
}
notify(data) {
this.observers.forEach(observer => observer.update(data)); // 通知观察者
}
}
class Observer {
constructor(name) {
this.name = name;
}
update(data) {
console.log(`${this.name} received:`, data);
}
}
// 测试
const subject = new Subject();
const observer1 = new Observer("Observer 1");
const observer2 = new Observer("Observer 2");
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify("Event Triggered!"); // 所有观察者收到通知
4. 策略模式 (Strategy)
特点:定义一系列算法,将每个算法封装起来,使它们可以互换。
用途:如表单校验逻辑、不同支付方式的处理。
class Validator {
constructor(strategy) {
this.strategy = strategy;
}
validate(value) {
return this.strategy(value);
}
}
// 策略函数
const isNotEmpty = value => value.trim() !== "";
const isNumber = value => !isNaN(value);
// 测试
const nonEmptyValidator = new Validator(isNotEmpty);
console.log(nonEmptyValidator.validate("Hello")); // true
console.log(nonEmptyValidator.validate("")); // false
const numberValidator = new Validator(isNumber);
console.log(numberValidator.validate("123")); // true
console.log(numberValidator.validate("abc")); // false
5. 装饰器模式 (Decorator)
特点:动态地给对象添加新的功能,而不改变其原始结构。
用途:如为组件添加额外功能(权限控制、日志记录等)。
function withLogging(component) {
return function (...args) {
console.log("Arguments:", args);
const result = component(...args);
console.log("Result:", result);
return result;
};
}
// 原始函数
function add(a, b) {
return a + b;
}
// 装饰后
const addWithLogging = withLogging(add);
// 测试
addWithLogging(3, 4);
// Logs:
// Arguments: [3, 4]
// Result: 7
6. 代理模式 (Proxy)
特点:为对象提供一个代理以控制对其的访问。
用途:常用于权限校验、延迟加载等。
const user = {
name: "John",
isAdmin: false,
};
const userProxy = new Proxy(user, {
get(target, prop) {
if (prop === "isAdmin" && !target[prop]) {
throw new Error("Unauthorized access");
}
return target[prop];
},
set(target, prop, value) {
if (prop === "isAdmin") {
console.log("Modifying admin rights is not allowed.");
return false;
}
target[prop] = value;
return true;
},
});
// 测试
try {
console.log(userProxy.isAdmin); // Throws "Unauthorized access"
} catch (e) {
console.error(e.message);
}
userProxy.name = "Jane"; // 修改 name 成功
console.log(userProxy.name); // "Jane"
7. 发布-订阅模式 (Publish-Subscribe)
特点:定义一种发布者与订阅者之间的关系,订阅者可以订阅感兴趣的事件。
用途:如消息总线或事件分发系统。
class EventBus {
constructor() {
this.events = {};
}
subscribe(event, listener) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(listener);
}
unsubscribe(event, listener) {
if (!this.events[event]) return;
this.events[event] = this.events[event].filter(l => l !== listener);
}
publish(event, data) {
if (!this.events[event]) return;
this.events[event].forEach(listener => listener(data));
}
}
// 测试
const bus = new EventBus();
const onMessage = data => console.log("Received:", data);
bus.subscribe("message", onMessage);
bus.publish("message", "Hello, World!"); // Received: Hello, World!
bus.unsubscribe("message", onMessage);
bus.publish("message", "Hello again!"); // 无输出
这几种设计模式在前端开发中都非常实用,可以根据场景灵活运用。需要具体代码示例或更多模式解析,可以随时告诉我!