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

传递方法、通用对象与事件特定对象的选型困惑

中介者模式中服务依赖传递的方案抉择分析

我在使用中介者模式时遇到了服务依赖传递的抉择问题:DAO类封装了针对数据库实体(表或列,按复杂度拆分)的通用操作,服务类依赖DAO实现业务逻辑,且我刻意避免直接把DAO传入中介者——这样做是为了方便单元测试和后续的依赖扩展。现在纠结于以下四种传递方案的选型:


方案1:传递完整服务对象

  • 实现方式:直接将完整的服务实例传入中介者
  • 示例代码:
const turn = new ServerTurnMediator(
  new DiceService(DiceDAO),
  new PlayerMoneyService(PlayerMoneyDAO)
)
  • 优劣分析:
    • 优势:实现成本最低,代码简洁,无需额外封装工作
    • 劣势:明确违反最小权限原则——中介者仅需服务的部分方法,却拥有了服务的全部能力,既增加了不必要的耦合,也存在误调用非必要方法的风险;后续服务新增方法时,中介者可能无意识依赖新方法,破坏封装性。

方案2:传递绑定后的特定方法

  • 实现方式:从服务实例中提取所需方法,通过bind绑定实例后传入中介者
  • 示例代码:
const playerMoneyService = new PlayerMoneyService(PlayerMoneyDAO);
const methodFromPlayerMoneyService = playerMoneyService.addMoneyToPlayer.bind(playerMoneyService);

const turn = new ServerTurnMediator(
  new DiceService(DiceDAO),
  methodFromPlayerMoneyService
)
  • 优劣分析:
    • 优势:严格遵循最小权限原则,中介者仅能获取所需方法,耦合度最低;单元测试时可直接传入模拟函数,灵活性极强
    • 劣势:若需多个方法,需重复执行绑定操作,代码会变得琐碎冗余;传递的孤立方法失去了服务对象的上下文语义,后续维护时难以识别方法归属,可读性差。

方案3:创建事件特定的服务对象

  • 实现方式:为中介者的特定场景创建专用服务类,这类服务仅包含中介者需要的方法,通过继承或组合复用原有服务逻辑,再将完整的专用服务传入中介者
  • 示例代码:
const turn = new ServerTurnMediator(
  new DiceService(DiceDAO),
  new PlayerMoneyIncreaserService(PlayerMoneyDAO)
)
  • 优劣分析:
    • 优势:完全符合单一职责原则,专用服务职责明确,仅处理特定场景业务;中介者获取的是语义清晰的服务对象,可读性与维护性俱佳;复用逻辑时可通过组合规避继承的弊端
    • 劣势:会增加类的数量,项目规模较大时可能出现大量细粒度服务类,提升代码管理成本;若多个中介者需要类似服务,可能产生重复的专用类。

方案4:DAO层构建对应继承/组合结构

  • 实现方式:在DAO层按业务场景拆分,创建专用DAO子类或组合类,让服务对象依赖这些专用DAO,再将服务传入中介者
  • 优劣分析:
    • 优势:将业务场景粒度下放到DAO层,服务类可更专注于业务逻辑,DAO职责也更细分;后续替换DAO实现时,专用DAO的接口更贴合业务,适配成本更低
    • 劣势:DAO层复杂度会上升,拆分过度可能导致DAO类数量爆炸;若业务场景变化频繁,DAO层的调整会影响上层服务,反而可能升高耦合度。

各方案适用场景及重构时机

  • 方案1:适用于小型项目或快速原型开发,优先保障开发效率,耦合风险可控的场景。
    重构时机:项目规模扩大,服务类方法增多,出现中介者误调用非必要方法的情况,或单元测试因服务依赖过多变得困难时。
  • 方案2:适用于中介者仅需服务1-2个方法,且后续不会新增依赖的场景。
    重构时机:需传递的方法超过3个,代码开始冗余,或维护时无法清晰识别方法所属上下文时,应重构为方案3。
  • 方案3:适用于中大型项目,对代码可读性、可维护性要求高,且业务场景划分清晰的情况。
    重构时机:专用服务类出现大量重复逻辑,或类数量过多导致管理困难时,可通过组合通用服务复用逻辑,或合并相似场景的专用服务。
  • 方案4:适用于DAO层本身逻辑复杂,且不同业务场景对数据库操作差异较大(如部分场景仅需读操作,部分需复杂写操作)的情况。
    重构时机:DAO层拆分导致重复代码过多,或上层服务所需DAO功能无法通过现有专用DAO满足时,应考虑用组合替代继承,或合并相似的专用DAO。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:30:22