行为型模式
📖 概述
行为型模式关注对象之间的通信和职责分配。这些模式定义了对象和类之间的交互方式,使系统更加灵活,能够适应变化的需求。
🎯 学习目标
- 掌握主要行为型设计模式的实现
- 理解对象间的协作和通信机制
- 学习责任链和状态模式的应用
- 实现观察者和策略模式的事件系统
👀 Observer 观察者模式
1. 事件系统实现
javascript
// 观察者接口
class Observer {
update(subject, data) {
throw new Error('update方法必须被实现')
}
}
// 主题/被观察者
class Subject {
constructor() {
this.observers = new Map()
this.state = {}
}
// 订阅观察者
subscribe(eventType, observer, options = {}) {
if (!(observer instanceof Observer) && typeof observer.update !== 'function') {
throw new Error('观察者必须实现update方法')
}
if (!this.observers.has(eventType)) {
this.observers.set(eventType, [])
}
const subscription = {
observer,
priority: options.priority || 0,
once: options.once || false,
filter: options.filter || null,
subscribed: new Date(),
id: this.generateSubscriptionId()
}
this.observers.get(eventType).push(subscription)
// 按优先级排序
this.observers.get(eventType).sort((a, b) => b.priority - a.priority)
console.log(`观察者订阅: ${eventType} (ID: ${subscription.id})`)
return subscription.id
}
// 取消订阅
unsubscribe(eventType, subscriptionId) {
if (!this.observers.has(eventType)) {
return false
}
const observers = this.observers.get(eventType)
const index = observers.findIndex(sub => sub.id === subscriptionId)
if (index !== -1) {
observers.splice(index, 1)
console.log(`取消订阅: ${eventType} (ID: ${subscriptionId})`)
return true
}
return false
}
// 通知观察者
notify(eventType, data = {}) {
if (!this.observers.has(eventType)) {
return
}
const eventData = {
type: eventType,
data: data,
subject: this,
timestamp: new Date()
}
console.log(`通知观察者: ${eventType}`)
const observers = this.observers.get(eventType).slice() // 复制数组避免修改
const toRemove = []
observers.forEach(subscription => {
try {
// 应用过滤器
if (subscription.filter && !subscription.filter(eventData)) {
return
}
// 调用观察者
subscription.observer.update(this, eventData)
// 处理一次性订阅
if (subscription.once) {
toRemove.push(subscription.id)
}
} catch (error) {
console.error(`观察者通知失败 [${subscription.id}]:`, error)
}
})
// 移除一次性订阅
toRemove.forEach(id => this.unsubscribe(eventType, id))
}
// 设置状态并通知
setState(newState) {
const oldState = { ...this.state }
this.state = { ...this.state, ...newState }
this.notify('stateChanged', {
oldState,
newState: this.state,
changes: newState
})
}
getState() {
return { ...this.state }
}
generateSubscriptionId() {
return `sub_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`
}
getSubscriptionCount(eventType) {
return this.observers.get(eventType)?.length || 0
}
getAllSubscriptions() {
const subscriptions = {}
this.observers.forEach((subs, eventType) => {
subscriptions[eventType] = subs.map(sub => ({
id: sub.id,
priority: sub.priority,
once: sub.once,
subscribed: sub.subscribed
}))
})
return subscriptions
}
}
// 具体观察者实现
class LoggerObserver extends Observer {
constructor(logLevel = 'info') {
super()
this.logLevel = logLevel
this.name = 'LoggerObserver'
}
update(subject, eventData) {
const logMessage = `[${this.logLevel.toUpperCase()}] ${eventData.type}: ${JSON.stringify(eventData.data)}`
console.log(`${eventData.timestamp.toISOString()} - ${logMessage}`)
}
}
class MetricsObserver extends Observer {
constructor() {
super()
this.name = 'MetricsObserver'
this.metrics = new Map()
}
update(subject, eventData) {
const eventType = eventData.type
if (!this.metrics.has(eventType)) {
this.metrics.set(eventType, {
count: 0,
lastOccurred: null,
firstOccurred: null
})
}
const metric = this.metrics.get(eventType)
metric.count++
metric.lastOccurred = eventData.timestamp
if (!metric.firstOccurred) {
metric.firstOccurred = eventData.timestamp
}
console.log(`指标更新: ${eventType} (总计: ${metric.count})`)
}
getMetrics() {
return Object.fromEntries(this.metrics)
}
getMetric(eventType) {
return this.metrics.get(eventType) || null
}
}
class EmailNotificationObserver extends Observer {
constructor(emailService) {
super()
this.emailService = emailService
this.name = 'EmailNotificationObserver'
}
update(subject, eventData) {
// 仅处理特定事件
const notifiableEvents = ['userRegistered', 'orderPlaced', 'paymentFailed']
if (!notifiableEvents.includes(eventData.type)) {
return
}
this.sendNotification(eventData)
}
async sendNotification(eventData) {
try {
const email = this.buildEmail(eventData)
await this.emailService.send(email)
console.log(`邮件通知发送: ${eventData.type}`)
} catch (error) {
console.error(`邮件通知发送失败: ${eventData.type}`, error)
}
}
buildEmail(eventData) {
const templates = {
userRegistered: {
subject: '欢迎注册!',
body: `欢迎 ${eventData.data.username} 加入我们!`
},
orderPlaced: {
subject: '订单确认',
body: `您的订单 ${eventData.data.orderId} 已确认`
},
paymentFailed: {
subject: '支付失败',
body: `订单 ${eventData.data.orderId} 支付失败,请重试`
}
}
const template = templates[eventData.type] || {
subject: '系统通知',
body: JSON.stringify(eventData.data)
}
return {
to: eventData.data.email || 'admin@example.com',
subject: template.subject,
body: template.body,
timestamp: eventData.timestamp
}
}
}
// 用户管理系统示例
class UserManager extends Subject {
constructor() {
super()
this.users = new Map()
}
async registerUser(userData) {
try {
console.log(`注册用户: ${userData.username}`)
// 验证用户数据
this.validateUserData(userData)
// 检查用户是否已存在
if (this.users.has(userData.username)) {
throw new Error('用户名已存在')
}
// 创建用户
const user = {
id: this.generateUserId(),
username: userData.username,
email: userData.email,
createdAt: new Date(),
status: 'active'
}
this.users.set(userData.username, user)
// 通知观察者
this.notify('userRegistered', {
userId: user.id,
username: user.username,
email: user.email
})
return user
} catch (error) {
// 通知注册失败
this.notify('userRegistrationFailed', {
username: userData.username,
error: error.message
})
throw error
}
}
async loginUser(username, password) {
try {
const user = this.users.get(username)
if (!user) {
throw new Error('用户不存在')
}
if (user.status !== 'active') {
throw new Error('用户账户已禁用')
}
// 模拟密码验证
console.log(`用户登录: ${username}`)
// 更新最后登录时间
user.lastLogin = new Date()
// 通知观察者
this.notify('userLoggedIn', {
userId: user.id,
username: user.username,
loginTime: user.lastLogin
})
return user
} catch (error) {
// 通知登录失败
this.notify('userLoginFailed', {
username: username,
error: error.message,
timestamp: new Date()
})
throw error
}
}
validateUserData(userData) {
if (!userData.username || userData.username.length < 3) {
throw new Error('用户名至少3个字符')
}
if (!userData.email || !this.isValidEmail(userData.email)) {
throw new Error('邮箱格式无效')
}
}
isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
generateUserId() {
return `user_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`
}
getUserCount() {
return this.users.size
}
getUser(username) {
return this.users.get(username)
}
}
🔗 Strategy 策略模式
1. 算法策略实现
javascript
// 策略接口
class Strategy {
execute(context, data) {
throw new Error('execute方法必须被实现')
}
getName() {
throw new Error('getName方法必须被实现')
}
getDescription() {
return this.getName()
}
}
// 具体策略:支付策略
class PaymentStrategy extends Strategy {
constructor() {
super()
this.fees = 0
this.processingTime = 0
}
calculateFee(amount) {
return amount * this.fees
}
getProcessingTime() {
return this.processingTime
}
}
class CreditCardPaymentStrategy extends PaymentStrategy {
constructor() {
super()
this.fees = 0.029 // 2.9%
this.processingTime = 3000 // 3秒
}
async execute(context, data) {
const { amount, cardInfo } = data
console.log(`处理信用卡支付: $${amount}`)
// 验证信用卡信息
this.validateCardInfo(cardInfo)
// 计算手续费
const fee = this.calculateFee(amount)
const totalAmount = amount + fee
// 模拟支付处理
await this.delay(this.processingTime)
// 模拟支付结果
const success = Math.random() > 0.1 // 90% 成功率
const result = {
success,
transactionId: this.generateTransactionId(),
amount,
fee,
totalAmount,
method: 'credit_card',
cardLast4: cardInfo.number.slice(-4),
timestamp: new Date()
}
if (!success) {
result.error = '信用卡支付被拒绝'
}
return result
}
validateCardInfo(cardInfo) {
if (!cardInfo.number || cardInfo.number.length < 13) {
throw new Error('无效的信用卡号')
}
if (!cardInfo.expiry || !this.isValidExpiry(cardInfo.expiry)) {
throw new Error('无效的过期日期')
}
if (!cardInfo.cvv || cardInfo.cvv.length < 3) {
throw new Error('无效的CVV')
}
}
isValidExpiry(expiry) {
const [month, year] = expiry.split('/')
const expiryDate = new Date(2000 + parseInt(year), parseInt(month) - 1)
return expiryDate > new Date()
}
getName() {
return 'CreditCardPayment'
}
getDescription() {
return `信用卡支付 (手续费: ${(this.fees * 100).toFixed(1)}%)`
}
generateTransactionId() {
return `cc_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
}
class PayPalPaymentStrategy extends PaymentStrategy {
constructor() {
super()
this.fees = 0.034 // 3.4%
this.processingTime = 2000 // 2秒
}
async execute(context, data) {
const { amount, paypalAccount } = data
console.log(`处理PayPal支付: $${amount}`)
// 验证PayPal账户
this.validatePayPalAccount(paypalAccount)
// 计算手续费
const fee = this.calculateFee(amount)
const totalAmount = amount + fee
// 模拟支付处理
await this.delay(this.processingTime)
// 模拟支付结果
const success = Math.random() > 0.05 // 95% 成功率
const result = {
success,
transactionId: this.generateTransactionId(),
amount,
fee,
totalAmount,
method: 'paypal',
account: paypalAccount.email,
timestamp: new Date()
}
if (!success) {
result.error = 'PayPal支付失败'
}
return result
}
validatePayPalAccount(account) {
if (!account.email || !this.isValidEmail(account.email)) {
throw new Error('无效的PayPal邮箱')
}
}
isValidEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
getName() {
return 'PayPalPayment'
}
getDescription() {
return `PayPal支付 (手续费: ${(this.fees * 100).toFixed(1)}%)`
}
generateTransactionId() {
return `pp_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
}
class BankTransferStrategy extends PaymentStrategy {
constructor() {
super()
this.fees = 0.01 // 1%
this.processingTime = 5000 // 5秒
}
async execute(context, data) {
const { amount, bankAccount } = data
console.log(`处理银行转账: $${amount}`)
// 验证银行账户
this.validateBankAccount(bankAccount)
// 计算手续费
const fee = this.calculateFee(amount)
const totalAmount = amount + fee
// 模拟转账处理
await this.delay(this.processingTime)
// 银行转账通常成功率很高
const success = Math.random() > 0.02 // 98% 成功率
const result = {
success,
transactionId: this.generateTransactionId(),
amount,
fee,
totalAmount,
method: 'bank_transfer',
bankName: bankAccount.bankName,
accountLast4: bankAccount.accountNumber.slice(-4),
timestamp: new Date()
}
if (!success) {
result.error = '银行转账失败'
}
return result
}
validateBankAccount(account) {
if (!account.accountNumber || account.accountNumber.length < 8) {
throw new Error('无效的银行账号')
}
if (!account.routingNumber || account.routingNumber.length !== 9) {
throw new Error('无效的路由号')
}
if (!account.bankName) {
throw new Error('银行名称不能为空')
}
}
getName() {
return 'BankTransfer'
}
getDescription() {
return `银行转账 (手续费: ${(this.fees * 100).toFixed(1)}%)`
}
generateTransactionId() {
return `bt_${Date.now()}_${Math.random().toString(36).substr(2, 8)}`
}
delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
}
// 策略上下文
class PaymentContext {
constructor() {
this.strategies = new Map()
this.defaultStrategy = null
this.currentStrategy = null
this.paymentHistory = []
}
// 注册策略
registerStrategy(name, strategy) {
if (!(strategy instanceof Strategy)) {
throw new Error('策略必须继承Strategy类')
}
this.strategies.set(name, strategy)
console.log(`注册支付策略: ${name}`)
if (!this.defaultStrategy) {
this.defaultStrategy = name
}
}
// 设置当前策略
setStrategy(strategyName) {
if (!this.strategies.has(strategyName)) {
throw new Error(`策略不存在: ${strategyName}`)
}
this.currentStrategy = strategyName
console.log(`切换支付策略: ${strategyName}`)
}
// 获取可用策略
getAvailableStrategies() {
const strategies = []
this.strategies.forEach((strategy, name) => {
strategies.push({
name,
description: strategy.getDescription(),
processingTime: strategy.getProcessingTime ? strategy.getProcessingTime() : 'N/A'
})
})
return strategies
}
// 自动选择最佳策略
selectBestStrategy(amount, criteria = {}) {
const availableStrategies = Array.from(this.strategies.entries())
// 根据标准评分
const scored = availableStrategies.map(([name, strategy]) => {
let score = 0
// 手续费权重
if (criteria.minimizeFees) {
const fee = strategy.calculateFee ? strategy.calculateFee(amount) : 0
score += criteria.minimizeFees * (1 - fee / amount)
}
// 处理时间权重
if (criteria.minimizeTime) {
const time = strategy.getProcessingTime ? strategy.getProcessingTime() : 5000
score += criteria.minimizeTime * (1 - time / 10000) // 假设最大10秒
}
// 可靠性权重(这里简化处理)
if (criteria.maximizeReliability) {
const reliability = this.getStrategyReliability(name)
score += criteria.maximizeReliability * reliability
}
return { name, strategy, score }
})
// 选择得分最高的策略
scored.sort((a, b) => b.score - a.score)
const best = scored[0]
console.log(`自动选择最佳策略: ${best.name} (得分: ${best.score.toFixed(2)})`)
return best.name
}
getStrategyReliability(strategyName) {
// 根据历史记录计算可靠性
const history = this.paymentHistory.filter(p => p.method === strategyName)
if (history.length === 0) {
return 0.9 // 默认可靠性
}
const successCount = history.filter(p => p.success).length
return successCount / history.length
}
// 执行支付
async executePayment(amount, paymentData, strategyName = null) {
const strategy = strategyName || this.currentStrategy || this.defaultStrategy
if (!strategy) {
throw new Error('未设置支付策略')
}
const strategyInstance = this.strategies.get(strategy)
if (!strategyInstance) {
throw new Error(`策略不存在: ${strategy}`)
}
try {
console.log(`执行支付: ${strategy}`)
const result = await strategyInstance.execute(this, {
amount,
...paymentData
})
// 记录支付历史
this.paymentHistory.push({
...result,
strategy: strategy
})
return result
} catch (error) {
console.error(`支付执行失败 [${strategy}]:`, error)
// 记录失败
this.paymentHistory.push({
success: false,
error: error.message,
strategy: strategy,
amount,
timestamp: new Date()
})
throw error
}
}
// 获取支付统计
getPaymentStatistics() {
const stats = {
totalPayments: this.paymentHistory.length,
successfulPayments: 0,
failedPayments: 0,
totalAmount: 0,
totalFees: 0,
strategyStats: {}
}
this.paymentHistory.forEach(payment => {
if (payment.success) {
stats.successfulPayments++
stats.totalAmount += payment.amount || 0
stats.totalFees += payment.fee || 0
} else {
stats.failedPayments++
}
// 策略统计
const strategyName = payment.strategy || 'unknown'
if (!stats.strategyStats[strategyName]) {
stats.strategyStats[strategyName] = {
count: 0,
successCount: 0,
totalAmount: 0
}
}
stats.strategyStats[strategyName].count++
if (payment.success) {
stats.strategyStats[strategyName].successCount++
stats.strategyStats[strategyName].totalAmount += payment.amount || 0
}
})
stats.successRate = stats.totalPayments > 0 ?
stats.successfulPayments / stats.totalPayments : 0
return stats
}
}
🔄 State 状态模式
1. 状态机实现
javascript
// 状态接口
class State {
constructor(name) {
this.name = name
}
enter(context) {
console.log(`进入状态: ${this.name}`)
}
exit(context) {
console.log(`退出状态: ${this.name}`)
}
handle(context, event) {
throw new Error('handle方法必须被实现')
}
canTransitionTo(targetState) {
return true // 默认允许所有转换
}
}
// 状态上下文
class StateMachine {
constructor(initialState) {
this.currentState = null
this.states = new Map()
this.transitions = new Map()
this.history = []
this.listeners = []
if (initialState) {
this.addState(initialState)
this.setState(initialState.name)
}
}
// 添加状态
addState(state) {
if (!(state instanceof State)) {
throw new Error('状态必须继承State类')
}
this.states.set(state.name, state)
console.log(`添加状态: ${state.name}`)
}
// 添加状态转换规则
addTransition(fromState, toState, event, condition = null) {
const transitionKey = `${fromState}:${event}`
if (!this.transitions.has(transitionKey)) {
this.transitions.set(transitionKey, [])
}
this.transitions.get(transitionKey).push({
toState,
condition
})
console.log(`添加转换: ${fromState} --[${event}]--> ${toState}`)
}
// 设置当前状态
setState(stateName) {
const newState = this.states.get(stateName)
if (!newState) {
throw new Error(`状态不存在: ${stateName}`)
}
if (this.currentState) {
// 检查是否允许转换
if (!this.currentState.canTransitionTo(newState)) {
throw new Error(`不允许从 ${this.currentState.name} 转换到 ${stateName}`)
}
this.currentState.exit(this)
}
const previousState = this.currentState
this.currentState = newState
// 记录状态变化历史
this.history.push({
from: previousState?.name || null,
to: newState.name,
timestamp: new Date()
})
this.currentState.enter(this)
// 通知监听器
this.notifyStateChange(previousState, newState)
}
// 处理事件
handleEvent(event, data = {}) {
if (!this.currentState) {
throw new Error('未设置当前状态')
}
console.log(`处理事件: ${event} (当前状态: ${this.currentState.name})`)
// 检查是否有定义的转换
const transitionKey = `${this.currentState.name}:${event}`
const transitions = this.transitions.get(transitionKey)
if (transitions) {
// 查找符合条件的转换
for (const transition of transitions) {
if (!transition.condition || transition.condition(this, event, data)) {
this.setState(transition.toState)
return
}
}
}
// 让当前状态处理事件
this.currentState.handle(this, event, data)
}
// 添加状态变化监听器
addStateChangeListener(listener) {
this.listeners.push(listener)
}
// 通知状态变化
notifyStateChange(fromState, toState) {
this.listeners.forEach(listener => {
try {
listener(fromState, toState, this)
} catch (error) {
console.error('状态变化监听器错误:', error)
}
})
}
// 获取当前状态
getCurrentState() {
return this.currentState
}
// 获取状态历史
getStateHistory() {
return [...this.history]
}
// 检查是否可以处理事件
canHandleEvent(event) {
if (!this.currentState) {
return false
}
const transitionKey = `${this.currentState.name}:${event}`
return this.transitions.has(transitionKey)
}
// 获取可用的转换
getAvailableTransitions() {
if (!this.currentState) {
return []
}
const available = []
this.transitions.forEach((transitions, key) => {
const [fromState, event] = key.split(':')
if (fromState === this.currentState.name) {
transitions.forEach(transition => {
available.push({
event,
toState: transition.toState,
hasCondition: !!transition.condition
})
})
}
})
return available
}
}
// 订单状态示例
class OrderState extends State {
constructor(name, allowedActions = []) {
super(name)
this.allowedActions = allowedActions
}
canPerformAction(action) {
return this.allowedActions.includes(action)
}
}
// 具体订单状态
class PendingOrderState extends OrderState {
constructor() {
super('pending', ['confirm', 'cancel', 'modify'])
}
handle(context, event, data) {
switch (event) {
case 'confirm':
this.confirmOrder(context, data)
break
case 'cancel':
this.cancelOrder(context, data)
break
case 'modify':
this.modifyOrder(context, data)
break
default:
console.warn(`待处理订单无法处理事件: ${event}`)
}
}
confirmOrder(context, data) {
console.log('确认订单...')
// 执行确认逻辑
if (this.validateOrder(context, data)) {
context.orderData = { ...context.orderData, ...data }
context.setState('confirmed')
} else {
console.error('订单确认失败')
}
}
cancelOrder(context, data) {
console.log('取消订单...')
context.cancelReason = data.reason || '用户取消'
context.setState('cancelled')
}
modifyOrder(context, data) {
console.log('修改订单...')
context.orderData = { ...context.orderData, ...data.changes }
console.log('订单修改完成,仍为待处理状态')
}
validateOrder(context, data) {
// 简单验证逻辑
return context.orderData && context.orderData.items && context.orderData.items.length > 0
}
}
class ConfirmedOrderState extends OrderState {
constructor() {
super('confirmed', ['ship', 'cancel'])
}
enter(context) {
super.enter(context)
// 进入确认状态时的操作
this.reserveInventory(context)
this.sendConfirmationEmail(context)
}
handle(context, event, data) {
switch (event) {
case 'ship':
this.shipOrder(context, data)
break
case 'cancel':
this.cancelOrder(context, data)
break
default:
console.warn(`已确认订单无法处理事件: ${event}`)
}
}
shipOrder(context, data) {
console.log('发货订单...')
context.trackingNumber = data.trackingNumber
context.shippedAt = new Date()
context.setState('shipped')
}
cancelOrder(context, data) {
console.log('取消已确认订单...')
// 释放库存
this.releaseInventory(context)
context.cancelReason = data.reason || '订单取消'
context.setState('cancelled')
}
reserveInventory(context) {
console.log('预留库存...')
// 预留库存逻辑
}
releaseInventory(context) {
console.log('释放库存...')
// 释放库存逻辑
}
sendConfirmationEmail(context) {
console.log('发送确认邮件...')
// 发送邮件逻辑
}
}
class ShippedOrderState extends OrderState {
constructor() {
super('shipped', ['deliver', 'return'])
}
enter(context) {
super.enter(context)
this.sendShippingNotification(context)
}
handle(context, event, data) {
switch (event) {
case 'deliver':
this.deliverOrder(context, data)
break
case 'return':
this.returnOrder(context, data)
break
default:
console.warn(`已发货订单无法处理事件: ${event}`)
}
}
deliverOrder(context, data) {
console.log('订单已送达...')
context.deliveredAt = new Date()
context.deliverySignature = data.signature
context.setState('delivered')
}
returnOrder(context, data) {
console.log('订单退货...')
context.returnReason = data.reason
context.returnedAt = new Date()
context.setState('returned')
}
sendShippingNotification(context) {
console.log(`发送发货通知,跟踪号: ${context.trackingNumber}`)
}
}
class DeliveredOrderState extends OrderState {
constructor() {
super('delivered', ['complete', 'return'])
}
enter(context) {
super.enter(context)
// 自动完成订单(7天后)
setTimeout(() => {
if (context.getCurrentState().name === 'delivered') {
context.handleEvent('complete', { autoCompleted: true })
}
}, 7 * 24 * 60 * 60 * 1000) // 7天
}
handle(context, event, data) {
switch (event) {
case 'complete':
this.completeOrder(context, data)
break
case 'return':
this.returnOrder(context, data)
break
default:
console.warn(`已送达订单无法处理事件: ${event}`)
}
}
completeOrder(context, data) {
console.log('完成订单...')
context.completedAt = new Date()
context.autoCompleted = data.autoCompleted || false
context.setState('completed')
}
returnOrder(context, data) {
console.log('送达后退货...')
context.returnReason = data.reason
context.returnedAt = new Date()
context.setState('returned')
}
}
class CompletedOrderState extends OrderState {
constructor() {
super('completed', [])
}
enter(context) {
super.enter(context)
this.processPayment(context)
this.updateAnalytics(context)
}
handle(context, event, data) {
console.warn(`已完成订单无法处理任何事件: ${event}`)
}
canTransitionTo(targetState) {
return false // 完成状态不能转换到其他状态
}
processPayment(context) {
console.log('处理最终付款...')
// 处理付款逻辑
}
updateAnalytics(context) {
console.log('更新分析数据...')
// 更新分析逻辑
}
}
class CancelledOrderState extends OrderState {
constructor() {
super('cancelled', [])
}
enter(context) {
super.enter(context)
this.processRefund(context)
this.logCancellation(context)
}
handle(context, event, data) {
console.warn(`已取消订单无法处理任何事件: ${event}`)
}
canTransitionTo(targetState) {
return false // 取消状态不能转换到其他状态
}
processRefund(context) {
console.log('处理退款...')
// 退款逻辑
}
logCancellation(context) {
console.log(`记录取消原因: ${context.cancelReason}`)
// 记录取消原因
}
}
// 订单管理系统
class OrderManager extends StateMachine {
constructor() {
super()
this.orderData = {}
this.setupStates()
this.setupTransitions()
this.setState('pending')
}
setupStates() {
this.addState(new PendingOrderState())
this.addState(new ConfirmedOrderState())
this.addState(new ShippedOrderState())
this.addState(new DeliveredOrderState())
this.addState(new CompletedOrderState())
this.addState(new CancelledOrderState())
}
setupTransitions() {
// 待处理 -> 已确认
this.addTransition('pending', 'confirmed', 'confirm',
(context, event, data) => {
return data.paymentConfirmed === true
})
// 待处理 -> 已取消
this.addTransition('pending', 'cancelled', 'cancel')
// 已确认 -> 已发货
this.addTransition('confirmed', 'shipped', 'ship',
(context, event, data) => {
return data.trackingNumber && data.trackingNumber.length > 0
})
// 已确认 -> 已取消
this.addTransition('confirmed', 'cancelled', 'cancel')
// 已发货 -> 已送达
this.addTransition('shipped', 'delivered', 'deliver')
// 已送达 -> 已完成
this.addTransition('delivered', 'completed', 'complete')
}
createOrder(orderData) {
this.orderData = {
id: this.generateOrderId(),
items: orderData.items,
customer: orderData.customer,
total: orderData.total,
createdAt: new Date()
}
console.log(`创建订单: ${this.orderData.id}`)
return this.orderData
}
generateOrderId() {
return `order_${Date.now()}_${Math.random().toString(36).substr(2, 6)}`
}
getOrderStatus() {
return {
orderId: this.orderData.id,
currentState: this.currentState.name,
canPerformActions: this.currentState.allowedActions,
availableTransitions: this.getAvailableTransitions(),
history: this.getStateHistory()
}
}
}
📚 最佳实践总结
- 观察者模式:实现松耦合的事件通知机制
- 策略模式:封装算法族,使算法可以互换
- 状态模式:将状态转换逻辑封装在状态对象中
- 命令模式:将请求封装成对象,支持撤销和重做
- 责任链模式:将请求沿着处理链传递
- 模板方法模式:定义算法骨架,子类实现具体步骤
- 访问者模式:在不修改对象结构的前提下定义新操作
- 中介者模式:用中介对象封装对象间的交互
通过掌握行为型模式,您将能够设计出更加灵活和可维护的对象交互机制。