一.是什么

调度器模式算是设计模式中的一种

调度器模式 = 在统一接口之下,根据能力位图(capabilityBitmap)将请求路由到不同的具体实现。

本质上是 策略模式 + 路由表 的结合:

  • 策略模式:所有子实现提供相同的 DiscoveryFuncInterface 接口
  • 路由表:每个子实现注册一个 IsConcern 谓词,调度器遍历路由表找到匹配的实现

二、为什么需要

BLE 发现不是一种,而是6 种业务场景共用 BLE 介质:

子实现 关注的能力 业务场景
SoftBus BLE castPlus, dvKit, osd 通用分布式发现
Share BLE share 跨设备分享
Approach BLE approach 靠近发现
VLink BLE virtualLink 虚拟链路
Touch BLE touch 触碰发现
OOP BLE oop OOP 发现

问题:Manager 层只给 BLE 一个 DiscoveryFuncInterface 指针,BLE 内部怎么区分这 6 种场景?

答案:加一层 Dispatcher,根据请求的 capabilityBitmap 自动路由到对应的子实现。


三、核心数据结构

DispatcherInterface — 路由表条目

从 disc_ble_dispatcher.h:35:

typedef struct {
    bool (*IsConcern)(uint32_t capability);   // 路由谓词:"我是否关注这个能力?"
    DiscoveryFuncInterface *mediumInterface;   // 具体实现接口
} DiscoveryBleDispatcherInterface;

路由表 — Dispatcher 数组

#define DISPATCHER_SIZE 6

static DiscoveryBleDispatcherInterface *g_dispatchers[DISPATCHER_SIZE];  // 6个槽位
static uint32_t g_dispatcherSize = 0;                                    // 当前注册数

每个子实现的 IsConcern

子实现 IsConcern 实现 关注的能力掩码
SoftBus BLE (capability & g_concernCapabilityMask) != 0 1<<3 | 1<<5 | 1<<7 (castPlus, dvKit, osd)
Share BLE IsShareConcern(capability) 1<<8 (share)
Approach BLE IsApproachConcern(capability) 1<<9 (approach)
VLink BLE return false (virtual实现) 1<<10 (virtualLink)
Touch BLE return false (virtual实现) 1<<11 (touch)
OOP BLE return false (virtual实现) 1<<12 (oop)

注意:VLink/Touch/OOP 的 virtual 实现 IsConcern 返回 false,表示当前平台不支持,真实实现(非 virtual)会返回对应的判断。


四、调度流程

请求到达时的路由过程

FindDiscoveryFuncInterface 核心代码

static DiscoveryFuncInterface *FindDiscoveryFuncInterface(uint32_t capability)
{
    for (uint32_t i = 0; i < g_dispatcherSize; i++) {
        if (g_dispatchers[i] == NULL) continue;
        if (g_dispatchers[i]->IsConcern != NULL && 
            g_dispatchers[i]->IsConcern(capability)) {     // ★ 路由判断
            return g_dispatchers[i]->mediumInterface;       // ★ 返回匹配的实现
        }
    }
    return NULL;  // 无匹配,返回NULL,调用方报错
}

五、初始化:注册路由表

从 disc_ble_dispatcher.c:226:

DiscoveryFuncInterface *DiscBleInit(DiscInnerCallback *discInnerCb)
{
    g_dispatcherSize = 0;

    // 注册5个基础 Dispatcher
    g_dispatchers[0] = DiscSoftBusBleInit(discInnerCb);    // SoftBus BLE (通用)
    g_dispatchers[1] = DiscShareBleInit(discInnerCb);      // Share BLE (分享)
    g_dispatchers[2] = DiscApproachBleInit(discInnerCb);   // Approach BLE (靠近)
    g_dispatchers[3] = DiscVLinkBleInit(discInnerCb);      // VLink BLE (虚拟链路)

    // 注册扩展 Dispatcher
    DiscBleInitExt(discInnerCb);
    //   g_dispatchers[4] = DiscTouchBleInit(discInnerCb);  // Touch BLE (触碰)
    //   g_dispatchers[5] = DiscOopBleInit(discInnerCb);    // OOP BLE

    return &g_discBleFrameFuncInterface;  // 返回统一接口给 Manager
}

每个 DiscXxxBleInit 返回一个 DiscoveryBleDispatcherInterface,包含该子实现的 IsConcern 和 mediumInterface


六、统一接口:Dispatcher 对 Manager 透明

Dispatcher 向上暴露一个 DiscoveryFuncInterface,Manager 完全不知道 Dispatcher 的存在:

static DiscoveryFuncInterface g_discBleFrameFuncInterface = {
    .Publish              = BleDispatchStartActivePublish,
    .StartScan            = BleDispatchStartPassivePublish,
    .Unpublish            = BleDispatchStopActivePublish,
    .StopScan             = BleDispatchStopPassivePublish,
    .StartAdvertise       = BleDispatchStartActiveDiscovery,
    .Subscribe            = BleDispatchStartPassiveDiscovery,
    .StopAdvertise        = BleDispatchStopActiveDiscovery,
    .Unsubscribe          = BleDispatchStopPassiveDiscovery,
    .LinkStatusChanged    = BleDispatchLinkStatusChanged,
    .UpdateLocalDeviceInfo = BleDispatchUpdateLocalDeviceInfo,
};

每个函数内部都走 FindDiscoveryFuncInterface → 具体实现的路由流程。


七、完整结构关系图

八、USB Dispatcher — 完全对称的设计

USB 发现采用完全相同的调度器模式,只是当前只有 1 个 Dispatcher:

#define DISPATCHER_SIZE 1

static DiscoveryUsbDispatcherInterface *g_usbDispatchers[DISPATCHER_SIZE];

路由逻辑与 BLE Dispatcher 代码几乎一模一样,只是把 g_dispatchers 换成 g_usbDispatchers


九、调度器模式 vs 其他方案

方案 优点 缺点
调度器模式(当前) 新增子实现只需注册 Dispatcher,不改调度逻辑 每次请求遍历路由表 O(N)
if-else 硬编码 简单直接 新增能力必须改调度代码,违反开闭原则
位图直接映射数组 O(1) 查找 一个能力只能对应一个实现,无法表达"SoftBus BLE 关注多种能力"
虚函数/接口继承 面向对象自然分发 C 语言没有虚函数,需手动实现 vtable

当前方案的核心优势IsConcern 是谓词而非等值匹配,所以 SoftBus BLE 可以一次声明关注 castPlus + dvKit + osd 三种能力,而不需要注册 3 次。这是位图直接映射做不到的。

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐