You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VBA工厂类循环引用致应用崩溃,求快速/优雅修复方案

Excel VBA工厂方法循环引用崩溃的修复方案

在Excel VBA项目中,我定义了多个类与接口:工作簿的每个工作表对应一个clsPmModule类的实例,这些实例由clsFactory类中的独立工厂方法创建。
基于OOP原则,工厂方法构建的类会调用其他工厂方法,动态创建并提供其他类的实例。此外,clsPmModule的每个实例可拥有观察者(OOP观察者模式),该类实现了IObservable与IObserver接口,并提供公共方法addObserver。
目前出现工厂方法调用的循环引用问题,导致应用崩溃。我曾尝试单例模式或通过自定义构造函数传递集合替代工厂方法调用,但未解决问题,求快速或优雅的修复方案?

clsFactory代码如下:

Public Function buildSomeInstance as clsPmModule

   Set buildSomeInstance = new clsPmModule
   with buildSomeInstance
      .constructor(...) '自定义构造函数
      .addObserver buildAnotherInstance
   end with

end function

Public Function buildAnotherInstance as clsPmModule

   Set buildAnotherInstance = new clsPmModule
   With buildAnotherInstance
      .constructor(...)   '自定义构造函数
      .bindValidationSource(buildSomeInstance) '循环引用
   End With

End Function

修复方案

方案1:拆分实例创建与依赖绑定(最优雅)

把实例创建和依赖关系绑定完全拆分,工厂只负责产出实例,单独用方法处理依赖关联,彻底规避循环调用:

  1. 修改clsFactory,拆分职责:
' 仅负责创建实例,不处理任何依赖
Public Function createSomeInstance() as clsPmModule
   Set createSomeInstance = new clsPmModule
   createSomeInstance.constructor(...)
End Function

Public Function createAnotherInstance() as clsPmModule
   Set createAnotherInstance = new clsPmModule
   createAnotherInstance.constructor(...)
End Function

' 单独处理依赖绑定逻辑
Public Sub initDependencies(someInst as clsPmModule, anotherInst as clsPmModule)
   someInst.addObserver anotherInst
   anotherInst.bindValidationSource someInst
End Sub
  1. 调用时先创建所有实例,再绑定依赖:
Dim someMod as clsPmModule, anotherMod as clsPmModule
Set someMod = clsFactory.createSomeInstance()
Set anotherMod = clsFactory.createAnotherInstance()
clsFactory.initDependencies someMod, anotherMod

方案2:延迟初始化依赖(快速修复)

如果不想大改现有结构,可将依赖改为延迟加载,不在工厂方法内直接触发对方实例的创建:

  1. 在clsPmModule中新增属性存储依赖引用,把绑定逻辑移到属性赋值时:
' clsPmModule类中添加
Private m_validationSource as clsPmModule
Private m_observer as clsPmModule

Public Property Set ValidationSource(source as clsPmModule)
   Set m_validationSource = source
   ' 这里执行原本bindValidationSource中的初始化逻辑
End Property

Public Property Set Observer(obs as clsPmModule)
   Set m_observer = obs
   Me.addObserver obs
End Property
  1. 修改工厂方法,仅完成实例基础构造:
Public Function buildSomeInstance() as clsPmModule
   Set buildSomeInstance = new clsPmModule
   buildSomeInstance.constructor(...)
End Function

Public Function buildAnotherInstance() as clsPmModule
   Set buildAnotherInstance = new clsPmModule
   buildAnotherInstance.constructor(...)
End Function
  1. 调用时手动赋值依赖:
Dim someMod as clsPmModule, anotherMod as clsPmModule
Set someMod = clsFactory.buildSomeInstance()
Set anotherMod = clsFactory.buildAnotherInstance()
Set someMod.Observer = anotherMod
Set anotherMod.ValidationSource = someMod

方案3:调整依赖绑定触发时机

通过事件或回调延迟依赖绑定,确保两个实例都已创建完成再建立引用:
比如在clsPmModule中添加实例创建完成的自定义事件,buildSomeInstance创建实例后订阅该事件,等anotherInstance创建完成后再执行addObserver;同理buildAnotherInstance也通过事件触发绑定验证源,避免在工厂方法内直接调用对方的创建方法。

内容的提问来源于stack exchange,提问作者user14181536

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 06:47:25