《C嵌入式编程设计模式》---读书笔记(2)

时间:2022-10-23 19:35:31

3.3 硬件适配器模式

    硬件适配器模式提供一种使已存在的硬件接口能适应期望应用的方法。

3.3.1 抽象

    当应用需要或使用一个接口而实际硬件提供另一种接口时,硬件适配器模式创建元素在两个接口之间进行转换。

3.3.2 问题

    当使用一个硬件设计替换另一个时,它们通常相似的功能,但是它们需要的信息和服务集合不同,此时创建硬件配适器可提供给客户期望的接口,最少化返工代码。

3.3.3 结构模式

    该模式通过添加硬件适配器、明确发布客户所期待的硬件支持接口,从而扩展了硬件代理模式。如下图:

《C嵌入式编程设计模式》---读书笔记(2)


3.3.4 协作角色

3.3.4.1 适配器客户

    配适器客户(Adapter Client)是应用系统中的一个元素,通过调用代表硬件的软件元素服务来控制、检测或使用硬件设备。

3.3.4.2 硬件适配器

    硬件适配器(Hardware Adapter)是将适配器客户执行的服务请求转换为一系列的硬件代理可执行的服务,包括服务调用因素、重新格式化以及重组数据。

3.3.4.3 客户硬件接口

    客户硬件接口(Hardware Interface to Client)表示客户期望硬件代理提供的一组服务和参数列表。

3.3.4.4 硬件设备

    参看硬件代理模式中的描述。

3.3.4.5 硬件代理

    参看硬件代理模式中的描述。

3.3.5 效果

    该模式允许使用各种硬件代理,从而在不同的应用中使用与其相关的硬件设备,同时允许已有的应用使用不同的硬件设备。配适器起连接胶合作用将硬件代理匹配到应用中,或者在一个新的应用中重用一个已经存在的硬件设备。

3.3.6 实现策略

    对象适配器形式:适配器子类化一个接口,并代理其他元素(本例使用)。

    类适配器形式:硬件适配器从接口和客户服务的重实现中子类化,包括其继承的代理服务,类适配器形式有更好的重用性。

3.3.7 相关模式

    硬件适配器模式扩展了硬件代理模式,其在客户和硬件代理之间添加中间层,使客户应用在不需改动的同时重用已经在其他系统中创建存在的硬件代理。硬件代理的实现和硬件适配器的实现能够合并,但是破坏了硬件代理的重用。

3.3.8 实例

    显示检测氧气浓度和氧气流量的系统,如下图所示。Gas Display客户端显示数据,Gas Mixer客户端将这些数据用于气体输送闭合循环控制。两者均使用io2Sensor的接口,io2Sensor包括两个服务gimmeO2Conc()、gimmeO2Flow()。系统可以与任意传感器交互,两传感器功能相似,但是提供不同编程接口。

《C嵌入式编程设计模式》---读书笔记(2)

    代码如下:

// AcmeO2Adapter.c
int AcmeO2Adapter_gimmeO2Conc(AcmeO2Adapter* const me) {
    return me->itsAcmeO2SensorProxy->getO2Conc();
}

int AcmeO2Adapter_gimmeO2Flow(AcmeO2Adapter* const me) {
    return (me->itsAcmeO2SensorProxy->getO2Flow()*60)/100;
}
// UltimateO2Adapter.c
int UltimateO2Adapter_gimmeO2Conc(UltimateO2Adapter* const me) {
    return int(me->getItsUltimateO2SensorProxy->accessO2Conc()*100);
    /*#]*/
}

int UltimateO2Adapter_gimmeO2Flow(UltimateO2Adapter* const me) {
    double totalFlow;                  
    // convert from liters/hr to cc/min
    totalFlow = me->itsUltimateO2SensorProxy->accessGasFlow() *
      1000.0/60.0;
    // now return the portion of the flow due to oxygen
    // and return it as an integer
    return (int)(totalFlow *me->itsUltimateO2SensorProxy->accessO2Conc());
}