-
设计模式
-
设计模式的概念
设计模式是在软件设计中经常遇到的问题的解决方案模型。它们是对历史经验的总结,与特定编程语言无关,可以应用于各种编程语言和领域。
-
设计模式背景
模式语言: 城镇、建筑、建造 (A Pattern Language: Towns, Buildings, Construction) 1977
在1977年,克里斯托弗·亚历山大提出了“模式语言”的概念,该概念适用于城镇规划、建筑设计和建筑施工。它主要强调了一套规则和指导原则,以帮助人们设计和建造更高质量的城市和建筑物。
设计模式: 可复用面向对象软件的基础 (Design Patterns: Elements of Reusable Object-Oriented Software) 1994
在1994年,《设计模式:可复用面向对象软件的基础》一书由四位作者(埃里希·伽玛、理查德·海尔姆、拉尔夫·约翰逊、约翰·威利斯迪斯)发布。这本书描述了23种常见的设计模式,并将它们分为创建型模式、结构型模式和行为型模式。
-
设计模式分类
设计模式可以分为以下三类:
- 创建型
创建型设计模式关注如何创建对象。它们提供了创建对象的机制,能够根据需求灵活地创建对象的实例。常见的创建型设计模式包括:
-
工厂模式(Factory Pattern)
-
抽象工厂模式(Abstract Factory Pattern)
-
单例模式(Singleton Pattern)
-
原型模式(Prototype Pattern)
-
建造者模式(Builder Pattern)
- 结构型
结构型设计模式关注如何将对象组装成较大的结构,以满足更复杂的功能需求。它们常常涉及对象之间的接口和关系,并通过简化对象之间的交互来简化系统结构。常见的结构型设计模式包括:
-
适配器模式(Adapter Pattern)
-
桥接模式(Bridge Pattern)
-
组合模式(Composite Pattern)
-
装饰器模式(Decorator Pattern)
-
外观模式(Facade Pattern)
-
享元模式(Flyweight Pattern)
-
代理模式(Proxy Pattern)
- 行为型
行为型设计模式关注对象间的高效通信和职责划分。它们处理对象之间的算法、职责和通信方式,以使系统更加灵活。常见的行为型设计模式包括:
-
责任链模式(Chain of Responsibility Pattern)
-
命令模式(Command Pattern)
-
解释器模式(Interpreter Pattern)
-
迭代器模式(Iterator Pattern)
-
中介者模式(Mediator Pattern)
-
备忘录模式(Memento Pattern)
-
观察者模式(Observer Pattern)
-
状态模式(State Pattern)
-
策略模式(Strategy Pattern)
-
模板方法模式(Template Method Pattern)
-
访问者模式(Visitor Pattern)
-
浏览器中的设计模式
单例模式
定义
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供全局唯一访问点。
应用场景
单例模式常用于需要全局访问的对象,例如缓存、全局状态管理等。
代码示例
// 单例对象
const Singleton = (function() {
let instance; // 保存单例实例
function init() {
// 私有方法和属性
function privateMethod() {
console.log("This is a private method");
}
let privateVariable = "This is a private variable";
return {
// 公共方法和属性
publicMethod: function() {
console.log("This is a public method");
},
publicVariable: "This is a public variable"
};
}
return {
// 获取单例实例
getInstance: function() {
if (!instance) {
instance = init();
}
return instance;
}
};
})();
// 使用单例对象
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true,两个实例相等
singleton1.publicMethod(); // This is a public method
console.log(singleton2.publicVariable); // This is a public variable
发布订阅模式
定义
发布订阅模式是一种订阅机制,允许在被订阅对象发生变化时通知订阅者。
应用场景
发布订阅模式可用于系统架构之间的解耦,以及业务中的实现模式,如邮件订阅、上线订阅等。
代码示例
// 发布订阅对象
const PubSub = (function() {
const subscribers = {}; // 订阅者列表
return {
// 订阅事件
subscribe: function(event, callback) {
if (!subscribers[event]) {
subscribers[event] = [];
}
subscribers[event].push(callback);
},
// 取消订阅
unsubscribe: function(event, callback) {
if (subscribers[event]) {
subscribers[event] = subscribers[event].filter(func => func !== callback);
}
},
// 发布事件
publish: function(event, data) {
if (subscribers[event]) {
subscribers[event].forEach(callback => callback(data));
}
}
};
})();
// 定义事件处理函数
function handleEvent1(data) {
console.log("Event 1:", data);
}
function handleEvent2(data) {
console.log("Event 2:", data);
}
// 订阅事件
PubSub.subscribe("event1", handleEvent1);
PubSub.subscribe("event2", handleEvent2);
// 发布事件
PubSub.publish("event1", "Hello");
PubSub.publish("event2", "World");
// 取消订阅
PubSub.unsubscribe("event1", handleEvent1);
// 再次发布事件
PubSub.publish("event1", "Hello again");
PubSub.publish("event2", "World again");
-
JavaScript中的设计模式
原型模式
定义
原型模式是一种对象创建的基本模式,它通过复制已有的对象来创建新的对象。
应用场景
原型模式在JavaScript中常用于对象创建,可以帮助我们快速创建和扩展对象实例。
代码示例
// 原型对象
const personPrototype = {
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
// 创建对象
const person1 = Object.create(personPrototype);
person1.name = "Alice";
person1.sayHello(); // Hello, my name is Alice
const person2 = Object.create(personPrototype);
person2.name = "Bob";
person2.sayHello(); // Hello, my name is Bob
代理模式
定义
代理模式允许我们自定义控制对原对象的访问方式,并且在更新前后可以执行一些额外操作。
应用场景
代理模式常用于监控、代理工具和前端框架的实现等情况。
代码示例
// 原对象
const realSubject = {
request: function() {
console.log("Real Subject: Processing request");
}
};
// 代理对象
const proxySubject = {
request: function() {
console.log("Proxy Subject: Logging before request");
realSubject.request();
console.log("Proxy Subject: Logging after request");
}
};
// 使用代理对象访问原对象
proxySubject.request();
迭代器模式
定义
迭代器模式允许我们在不暴露数据类型的情况下访问集合中的元素。
应用场景
迭代器模式常用于处理包含多种数据类型的数据结构,如列表、树等,为它们提供通用的操作接口。
代码示例
// 迭代器对象
const iterator = {
index: 0,
data: [1, 2, 3, 4, 5],
next: function() {
return this.hasNext() ? this.data[this.index++] : null;
},
hasNext: function() {
return this.index < this.data.length;
}
};
// 使用迭代器遍历数据
while (iterator.hasNext()) {
console.log(iterator.next());
}
-
框架中的设计模式
组合模式
定义
组合模式允许多个对象组合使用,同时也可以单独使用每个对象。
应用场景
组合模式常用于DOM操作、前端组件开发、文件目录结构等情况。