第一章:JavaScript设计模式概述
JavaScript 设计模式是开发者在长期实践中总结出的可复用解决方案,用于应对常见的软件设计问题。这些模式不提供具体的代码实现,而是描述了一种结构化思路,帮助提升代码的可维护性、可扩展性和可读性。在动态语言如 JavaScript 中,设计模式尤为重要,因为其灵活性和弱类型特性容易导致代码结构混乱。为何使用设计模式
- 提高代码复用性,减少重复逻辑
- 增强模块间的解耦,便于单元测试
- 促进团队协作,统一架构理解
常见设计模式分类
| 类别 | 典型模式 | 用途说明 |
|---|---|---|
| 创建型 | 工厂模式、单例模式 | 控制对象的创建过程 |
| 结构型 | 装饰器模式、适配器模式 | 处理类与对象的组合关系 |
| 行为型 | 观察者模式、策略模式 | 定义对象间通信机制 |
观察者模式示例
// 定义一个简单的事件中心
class EventEmitter {
constructor() {
this.events = {}; // 存储事件名与回调函数
}
// 订阅事件
on(event, callback) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
// 触发事件
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
}
// 使用示例
const bus = new EventEmitter();
bus.on('userLogin', user => console.log(`欢迎 ${user.name}`));
bus.emit('userLogin', { name: 'Alice' }); // 输出:欢迎 Alice
graph LR
A[Subject] -->|通知| B(Observer 1)
A -->|通知| C(Observer 2)
A -->|通知| D(Observer 3)
第二章:创建型设计模式
2.1 工厂模式:统一对象创建流程
工厂模式是一种创建型设计模式,用于在不指定具体类的情况下创建对象。它将对象的实例化逻辑集中到一个专门的工厂类中,提升代码的可维护性与扩展性。核心优势
- 解耦对象使用与创建过程
- 支持开闭原则,便于新增产品类型
- 统一管理对象生成逻辑
简单工厂示例
type Product interface {
GetName() string
}
type ConcreteProductA struct{}
func (p *ConcreteProductA) GetName() string {
return "Product A"
}
type ProductFactory struct{}
func (f *ProductFactory) CreateProduct(typeName string) Product {
switch typeName {
case "A":
return &ConcreteProductA{}
default:
return nil
}
}
上述代码中,ProductFactory 根据传入的类型字符串返回对应的实现对象,调用方无需了解具体构造细节。参数 typeName 控制产品类型分支,便于集中维护。
2.2 单例模式:确保全局唯一实例
单例模式是一种创建型设计模式,确保一个类仅有一个实例,并提供全局访问点。在高并发或资源敏感场景中,避免重复初始化至关重要。经典实现方式
type Singleton struct{}
var instance *Singleton
var once sync.Once
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})
return instance
}
上述 Go 语言实现利用 sync.Once 保证初始化仅执行一次。GetInstance 函数是获取实例的唯一入口,线程安全且延迟初始化。
应用场景与注意事项
- 配置管理器:全局共享配置状态
- 日志记录器:统一输出格式与目标
- 数据库连接池:控制资源使用上限
2.3 建造者模式:分步构建复杂对象
核心思想与适用场景
建造者模式用于将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。适用于包含多个组成部分且构造流程稳定的对象,如配置对象、UI组件或请求报文。代码实现示例
type Computer struct {
CPU string
RAM string
Disk string
}
type ComputerBuilder struct {
computer *Computer
}
func NewComputerBuilder() *ComputerBuilder {
return &ComputerBuilder{computer: &Computer{}}
}
func (b *ComputerBuilder) SetCPU(cpu string) *ComputerBuilder {
b.computer.CPU = cpu
return b
}
func (b *ComputerBuilder) SetRAM(ram string) *ComputerBuilder {
b.computer.RAM = ram
return b
}
func (b *ComputerBuilder) Build() *Computer {
return b.computer
}
上述代码通过链式调用逐步设置属性,最终调用 Build() 返回完整对象,避免了构造函数参数过多的问题。
优势对比
| 方式 | 可读性 | 扩展性 |
|---|---|---|
| 构造函数 | 低 | 差 |
| 建造者模式 | 高 | 优 |
2.4 原型模式:高效复制现有对象结构
原型模式是一种创建型设计模式,通过复制已有实例来创建新对象,避免重复初始化过程,提升性能。核心思想与应用场景
该模式适用于对象创建成本较高,且对象结构相似的场景。通过克隆原型实例,可快速生成配置相同的对象副本。- 减少new操作带来的资源消耗
- 动态配置对象的运行时行为
- 适用于复杂对象或继承体系的复制
Go语言实现示例
type Prototype interface {
Clone() Prototype
}
type ConcretePrototype struct {
Name string
Data map[string]interface{}
}
func (p *ConcretePrototype) Clone() Prototype {
// 深拷贝字段,防止引用共享
newData := make(map[string]interface{})
for k, v := range p.Data {
newData[k] = v
}
return &ConcretePrototype{Name: p.Name, Data: newData}
}
上述代码定义了原型接口和具体实现。Clone方法执行深拷贝,确保副本与原对象独立,避免数据污染。Name字段直接复制,Data字段逐项拷贝以实现深复制逻辑。
2.5 抽象工厂模式:创建相关对象族的解决方案
抽象工厂模式是一种创建型设计模式,用于构建一组相关或依赖对象的家族,而无需指定其具体类。它通过定义一个创建对象的接口,使得子类可以决定实例化哪一个工厂类。核心结构与角色
- 抽象工厂(Abstract Factory):声明创建一系列产品的方法。
- 具体工厂(Concrete Factory):实现抽象工厂接口,生成具体的产品对象。
- 抽象产品(Abstract Product):定义产品的接口。
- 具体产品(Concrete Product):实现抽象产品接口的实际对象。
代码示例
type GUIFactory interface {
CreateButton() Button
CreateCheckbox() Checkbox
}
type WindowsFactory struct{}
func (f *WindowsFactory) CreateButton() Button {
return &WindowsButton{}
}
func (f *WindowsFactory) CreateCheckbox() Checkbox {
return &WindowsCheckbox{}
}
上述代码定义了一个跨平台UI组件工厂,WindowsFactory 可统一创建按钮和复选框等配套控件,确保界面风格一致性。通过接口隔离创建逻辑,客户端无需关心对象的具体实现。
第三章:结构型设计模式
3.1 装饰器模式:动态扩展对象功能
装饰器模式是一种结构型设计模式,允许在不修改对象本身的前提下动态地为对象添加新功能。通过将功能封装在装饰器类中,实现职责的灵活组合。核心思想与结构
装饰器模式基于“组合优于继承”的原则,使用抽象组件定义统一接口,具体组件实现基础行为,而装饰器持有组件引用并附加额外职责。- Component:定义对象接口
- ConcreteComponent:具体实现组件
- Decorator:持有一个组件对象,提供基本的包装功能
- ConcreteDecorator:添加具体功能
代码示例(Go语言)
type Component interface {
Operation() string
}
type ConcreteComponent struct{}
func (c *ConcreteComponent) Operation() string {
return "基础功能"
}
type Decorator struct {
component Component
}
func (d *Decorator) Operation() string {
return d.component.Operation()
}
type ConcreteDecoratorA struct {
Decorator
}
func (da *ConcreteDecoratorA) Operation() string {
return "增强功能A -> " + da.Decorator.Operation()
}
上述代码中,ConcreteDecoratorA 在保留原对象行为的基础上,前置了新的处理逻辑,实现了功能的叠加。这种结构支持运行时动态嵌套多个装饰器,具备高度灵活性。
3.2 适配器模式:兼容不匹配接口的桥梁
在软件开发中,不同系统或组件间的接口不兼容是常见问题。适配器模式通过封装一个类的接口,使其符合客户端期望的另一个接口,从而实现无缝协作。典型应用场景
当需要复用一些功能类,但其接口与当前系统不一致时,适配器充当“中间转换层”,无需修改原有代码即可集成。结构与实现
适配器模式包含三个核心角色:- 目标接口(Target):客户端期待的接口
- 适配者(Adaptee):已存在的接口,需被适配
- 适配器(Adapter):将适配者接口转换为目标接口
type Target interface {
Request()
}
type Adaptee struct{}
func (a *Adaptee) SpecificRequest() {
fmt.Println("Adaptee执行特殊请求")
}
type Adapter struct {
adaptee *Adaptee
}
func (a *Adapter) Request() {
a.adaptee.SpecificRequest() // 转换调用
}
上述代码中,Adapter 包装了 Adaptee 实例,并在其 Request() 方法中调用 SpecificRequest(),实现了接口转换。
3.3 代理模式:控制对象访问的安全屏障
代理模式是一种结构型设计模式,用于为真实对象提供一个代理,以控制对它的访问。代理可在不改变原始接口的前提下,实现权限校验、延迟加载、日志记录等附加操作。代理模式的核心角色
- Subject(抽象主题):定义真实对象和代理的公共接口
- RealSubject(真实主题):具体业务逻辑的执行者
- Proxy(代理):持有真实对象的引用,控制访问
代码示例:Go 中的代理实现
type Service interface {
Request() string
}
type RealService struct{}
func (r *RealService) Request() string {
return "处理真实请求"
}
type Proxy struct {
realService *RealService
}
func (p *Proxy) Request() string {
if p.checkAccess() {
p.realService = &RealService{}
return p.realService.Request()
}
return "拒绝访问"
}
func (p *Proxy) checkAccess() bool {
// 模拟权限检查
return true
}
上述代码中,Proxy 在调用 RealService 前执行访问控制,实现了安全隔离。参数说明:checkAccess() 模拟权限逻辑,仅当通过时才创建真实对象并转发请求。
第四章:行为型设计模式
4.1 观察者模式:实现事件驱动的通信机制
观察者模式是一种行为设计模式,允许对象在状态变化时自动通知其依赖者,广泛应用于事件驱动系统中。核心结构与角色
该模式包含两个主要角色:**主题(Subject)** 和 **观察者(Observer)**。主题维护观察者列表,并在状态变更时触发通知。- Subject:管理观察者注册与通知机制
- Observer:定义接收更新的接口
Go语言实现示例
type Subject interface {
Register(Observer)
Notify()
}
type ConcreteSubject struct {
observers []Observer
state string
}
func (s *ConcreteSubject) Register(o Observer) {
s.observers = append(s.observers, o)
}
func (s *ConcreteSubject) Notify() {
for _, o := range s.observers {
o.Update(s.state)
}
}
上述代码中,ConcreteSubject 维护观察者列表并通过 Notify() 方法广播状态变化。每个观察者实现 Update() 方法以响应更新,从而实现松耦合的通信机制。
4.2 策略模式:封装可互换的算法家族
策略模式是一种行为设计模式,它允许在运行时动态选择算法。通过将算法封装在独立的策略类中,客户端可以灵活切换不同实现,而无需修改核心逻辑。核心结构
策略模式包含三个关键角色:- 上下文(Context):持有策略接口引用,调用具体算法。
- 策略接口(Strategy):定义所有支持算法的公共操作。
- 具体策略(Concrete Strategy):实现策略接口的不同算法。
代码示例
type PaymentStrategy interface {
Pay(amount float64) string
}
type CreditCard struct{}
func (c *CreditCard) Pay(amount float64) string {
return fmt.Sprintf("Paid %.2f via Credit Card", amount)
}
type PayPal struct{}
func (p *PayPal) Pay(amount float64) string {
return fmt.Sprintf("Paid %.2f via PayPal", amount)
}
上述代码定义了支付策略接口及两种实现。PaymentStrategy 抽象了支付方式,CreditCard 和 PayPal 为具体策略。上下文可通过注入不同策略实例来改变支付行为,提升系统灵活性与可扩展性。
4.3 命令模式:将操作封装为可调用对象
命令模式是一种行为设计模式,它将请求封装为独立对象,从而使你可以用不同的请求对客户端进行参数化。核心结构与角色
- Command:声明执行操作的接口
- ConcreteCommand:实现具体操作逻辑
- Invoker:触发命令执行
- Receiver:真正执行业务逻辑的对象
代码示例
type Command interface {
Execute()
}
type LightOnCommand struct {
light *Light
}
func (c *LightOnCommand) Execute() {
c.light.TurnOn()
}
上述代码定义了一个打开灯的命令。LightOnCommand 封装了对 Light 对象的操作,使调用者无需了解灯的具体开启细节,仅需调用 Execute 方法即可完成操作,实现了调用者与接收者之间的解耦。
4.4 状态模式:让对象行为随状态变化而切换
状态模式是一种行为设计模式,允许对象在内部状态改变时动态修改其行为。通过将状态封装为独立类,实现状态与行为的解耦。核心结构
状态模式包含上下文(Context)和具体状态类。上下文持有当前状态对象,并将状态相关的行为委托给状态实例。type State interface {
Handle(context *Context)
}
type Context struct {
state State
}
func (c *Context) Request() {
c.state.Handle(c)
}
上述代码定义了状态接口与上下文。Handle 方法根据当前状态执行不同逻辑,调用 Request 时自动触发对应行为。
状态切换示例
- 初始状态:Pending —— 可执行启动操作
- 运行状态:Running —— 支持暂停或停止
- 终止状态:Stopped —— 仅允许重置
第五章:总结与最佳实践
性能优化策略
在高并发系统中,数据库查询往往是瓶颈所在。使用连接池并合理配置最大连接数可显著提升响应速度。例如,在 Go 应用中使用 `sql.DB` 时应设置合理的参数:// 设置数据库连接池
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(25)
db.SetConnMaxLifetime(5 * time.Minute)
安全配置建议
生产环境必须启用 HTTPS 并配置安全头。Nginx 配置示例如下:- 启用 HSTS:
add_header Strict-Transport-Security "max-age=31536000" always; - 防止点击劫持:
add_header X-Frame-Options "DENY"; - 启用内容安全策略:
add_header Content-Security-Policy "default-src 'self';";
部署流程标准化
使用 CI/CD 流水线确保发布一致性。以下为典型阶段划分:| 阶段 | 操作 | 工具示例 |
|---|---|---|
| 构建 | 编译代码、生成镜像 | Docker, Make |
| 测试 | 运行单元与集成测试 | JUnit, pytest |
| 部署 | 蓝绿发布至生产 | Kubernetes, ArgoCD |
监控与告警机制
关键指标应持续采集:
- 请求延迟(P95/P99)
- 错误率超过阈值触发告警
- 资源利用率(CPU、内存、磁盘 I/O)
推荐使用 Prometheus + Grafana 实现可视化监控。
1258

被折叠的 条评论
为什么被折叠?



