行为设计模式是一类用于描述对象之间通信与职责分配的设计模式,关注“对象之间的交互”和“职责的分配”

发布时间:2026/7/28 4:41:10
行为设计模式是一类用于描述对象之间通信与职责分配的设计模式,关注“对象之间的交互”和“职责的分配” 行为设计模式是一类用于描述对象之间通信与职责分配的设计模式关注“对象之间的交互”和“职责的分配”。你提到的四种模式——观察者Observer、策略Strategy、命令Command和职责链Chain of Responsibility——均属于经典GoF 23种设计模式中的行为型模式各自解决不同场景下的行为解耦与动态变化问题观察者模式定义对象间一对多的依赖关系当一个对象状态改变时所有依赖它的对象自动得到通知并更新如事件监听、MVC中的View-Model联动。策略模式封装一系列算法使它们可以互相替换让算法的变化独立于使用它的客户端如支付方式选择微信支付、支付宝、银行卡等策略可动态切换。命令模式将请求封装为对象从而可用不同的请求对客户进行参数化、支持撤销/重做、日志记录和队列操作如GUI按钮点击、宏命令、任务调度系统。职责链模式使多个对象都有机会处理请求避免请求发送者与接收者耦合将这些对象连成一条链并沿链传递请求直到被处理如审批流程组长→部门经理→HR→CEO逐级处理。这四者共性在于降低对象间的紧耦合提升行为的可扩展性与可维护性差异在于关注点不同——观察者聚焦“状态变更通知”策略聚焦“算法替换”命令聚焦“请求封装与控制”职责链聚焦“请求分发与响应权移交”。# 示例简易策略模式实现支付策略fromabcimportABC,abstractmethodclassPaymentStrategy(ABC):abstractmethoddefpay(self,amount:float)-str:passclassWeChatPay(PaymentStrategy):defpay(self,amount:float)-str:returnf微信支付{amount}元classAlipay(PaymentStrategy):defpay(self,amount:float)-str:returnf支付宝支付{amount}元classPaymentContext:def__init__(self,strategy:PaymentStrategy):self._strategystrategydefexecute_payment(self,amount:float)-str:returnself._strategy.pay(amount)# 使用ctxPaymentContext(WeChatPay())print(ctx.execute_payment(99.9))# 微信支付 99.9 元在观察者模式中内存泄漏常源于循环引用circular reference被观察者Subject持有了观察者Observer的强引用而观察者又可能通过回调、闭包或内部类等方式持有被观察者的引用导致垃圾回收器无法释放对象尤其在长期运行系统如GUI应用、服务端事件总线中尤为关键。✅ Java 中的典型解决方案使用弱引用WeakReference管理观察者将观察者存入WeakReferenceObserver列表使GC可在无其他强引用时回收观察者避免被观察者阻止其销毁publicclassSubject{privatefinalListWeakReferenceObserverobserversnewArrayList();publicvoidaddObserver(Observerobs){observers.add(newWeakReference(obs));}publicvoidnotifyObservers(){// 过滤已回收的观察者observers.removeIf(ref-ref.get()null);observers.forEach(ref-{Observerobsref.get();if(obs!null)obs.update(this);});}}显式解注册Unregistertry-finally/AutoCloseable要求观察者在生命周期结束前调用removeObserver()配合try-with-resources或Disposable接口如RxJava的Disposable确保清理。使用java.util.concurrent.CopyOnWriteArrayList 显式管理线程安全但需配合手动移除逻辑适用于观察者数量少、变更不频繁场景。框架级方案Android 中LiveData内部使用LifecycleOwner绑定生命周期自动解注册Spring 的ApplicationEventPublisher配合EventListener与SmartLifecycle实现自动销毁感知。✅ Python 中的典型解决方案使用weakref.WeakKeyDictionary或weakref.WeakSetWeakKeyDictionary以观察者为 key自动在观察者被回收时剔除条目要求观察者是可哈希的WeakSet更通用支持任意对象importweakrefclassSubject:def__init__(self):self._observersweakref.WeakSet()# 自动清理已销毁的observerdefattach(self,observer):self._observers.add(observer)defnotify(self,data):# WeakSet 迭代时自动跳过已回收对象forobsinlist(self._observers):# list() 防止迭代中修改obs.update(data)避免闭包捕获self引用尤其在 lambda 或嵌套函数中❌ 危险示例defregister(self,obj):self.observers.append(lambda:self.handle(obj))# 捕获 self → 循环引用✅ 安全替代用functools.partial或显式传参或改用绑定方法obj.method是 bound method但需确保obj不反向引用self。上下文管理器with语句或__del__辅助清理慎用更推荐显式unregister() 上下文协议如contextlib.closing因__del__执行时机不确定且不可靠。现代方案asyncio事件总线 weakref.ref回调在异步系统中结合asyncio.create_task()和弱引用回调避免任务长期持有对象引用。✅共性最佳实践观察者应无状态或弱依赖被观察者被观察者不持有观察者的业务逻辑引用仅保留通知能力在 GUI/Android/前端框架中严格绑定生命周期如onDestroy()、useEffect cleanup使用静态分析工具JavaLeakCanaryPythonobjgraph、tracemalloc检测潜在泄漏。