表模块模式(Table Module)

本文探讨了表模块(table module)设计模式的概念及其在业务逻辑层的应用。对比领域模型(domain model)和事务脚本(transaction script),介绍了表模块模式的特点、优势及局限性,并通过实例展示了其在数据驱动应用中的有效性。

    (大量参考PoEAA...-_-...)


    最近网上看到这样的帖子<<谁能告诉我Hibernate有何优秀之处>> 作者给出了对hibernate在实现orm的诸多不满和怀疑。而且很多开发人员都有着这样疑问,“怎么这个流行东东,我用起来就是不顺手呢?,“或许这个东东只是用来吹牛的”。然而,这或许很可能是因为,你习惯的架构模式开发策略并不适合使用orm这种持久化模式。用了反而是加大复杂度降低性能和效率。比如,用惯了resultset,喜欢把resultset放在表示层作为展示的数据结构的人。这样的开发人员因为习惯了二维表为核心进行开发,对于Hibernate这样的orm工具根本就没办法了解其优势了。但是这并不是说这种以二维表的架构模式就比较差了,只是不同的模式有不同的优缺点就看所在的应用是否适合使用了。或许你就一直在使用这样的模式在开发应用,自己还没有意识到(甚至一直以为这样的方式可以适应任何应用,:-)。反而被其他架构模式中才会用到的框架搞的晕头转向甚至被误导。事实上,像前面提到的以二维表为核心的架构被称之为表模块架构(设计)模式。

       何为“表模块”(table module)?“处理某一个数据库表、视图或虚拟表中所有行为的业务逻辑组成的一个实例”。最初,我就是从马丁同学的POEAA中得到的这个定义。在书中他被定义在DomainLogic 层次或者该层次的一部分,DomainLogic也就是其他架构模型中的BizLogic层。与该模式相对应个还有完成相似功能的DomainModel以及TransactionScript模式。该层次的职责是专门处理业务逻辑。

       简单的讲,所谓“表模块”就是以一个类对应数据库中一个表(视图)的数据来组织业务逻辑。从设计层次表妙面上看这种结构很像经典OO模型,同样是以不同对象对应不同逻辑。但是,它与领域建模不同之处在于,它的对象并不表示一个问题领域对象在软件系统中的映射。而是表示对一组数据的处理逻辑,而通常这组数据的结构是重数据库表或试图上的二维数据结构。当然也可以来自其他集成部分,比如返回两位数据结构的webservice

       这里给出个比较形象的例子:

oo.jpg

       (上图)感觉像比较标准的OO吧,好象一个Contract的对象表示合同,而Product表示产品,还有他们之间的关联关系。但是其实现实给出几个方法的时候就看出区别了。Product内部的数据其实就是一个两位结构的rowset。而不像真正的领域模型分析出来的表示一个Product的数据,Contract也是如此。

tableModule.jpg

       你会发现tableModule的类中一个对象其实对应一个表的数据,其拥有的操作也有很多是多数据记录的。多数据记录的操作在真正的领域中往往应该放在类似Manager这样的实体中,而不是业务实体本身。

       使用这种模式实现的业务逻辑层不像领域模型模式可以适应搞复杂度的逻辑。但是由于它更亲近于数据持久的二维表,没有像领域模型那样需要复杂的ORM支持。书对于数据驱动的应用或模块非常适合。POEAA中也已经给出了这种bizLogic最有效的持久层实现,就是table getway,当然也可以使用其他的方式比如“查询工厂”。

       事实上,最多使用这种模式的情况是当后台数据源大部分都是一种两维甚至多维数据结构的时候进行。比如一个极端的例子(几乎没有业务),一个应用的复杂查询模块,这种模块就是一个查询模型加上一组对数据进行排列统计过滤的TableModule

       tableModule_Meta.JPG

       表模块还具有很多特点:处理的二维数据表将成为代码的核心部分。所以,是否使用tableModule还会取决于整个应用的其他部分是否对这种二维表提供强大的支持。(如上图)

       优点:持久层架构简单,在复杂度大的以数据为核心的应用中开发效率极高。而且表模块能够识别的table越多,能够处理table的组建工具越强,这种模型的能力越强。

       缺点:不能适应复杂的应用逻辑,或者与表结构差别较大的应用逻辑。由于没有对内部的两位数据表(table)进行有效标识的方式(比如,无法快速简单的确定使用table是否是需要的数据内容),对于大量细颗粒的逻辑会增加其复杂度。

       其实java中的 rowset/jdbc resultset.net中的 dateSet/dataTable都属于表模块操作的二维表。但是,由于.netGUI层面以及持久化层面对他自己的二维表的强大支持使得 TableModule几乎成为MS.Net上的首选模式。这也就可以解释了,许多.net开发人员一直抱怨,看到dataset/dataTable泛滥,甚至在WebService中也是这样。而java中却有所不同,虽然有持久化用到的jdbc/resultSet的支持(事实上jdbc/ado 给出的接口都只直接适合TableModule。),然而其他方面就少得可怜了。所以,使用java还是以其他的bizLogic架构模式为好。除非你的逻辑真的很简单,简单到把resultSet放在jsp中都不会造成逻辑混乱。又或者你能够自己提供一套完整的 rowset组建框架。

<think>好的,我现在需要帮助用户查找关于模块中断号与中断向量的相关信息,特别是在嵌入式系统编程中的内容。首先,我需要明确这两个概念的定义和它们在嵌入式系统中的角色。 用户提到的“模块中断号”应该是指特定硬件模块(如定时器、UART、GPIO等)所对应的中断编号。每个硬件设备在系统中通常会有一个唯一的中断号,用来标识其中断请求。而“中断向量”是一个存储中断处理程序(ISR)入口地址的数组或格,中断号对应向量中的索引,系统通过这个索引找到相应的处理程序。 接下来,我需要回忆嵌入式系统中中断处理的基本流程。当硬件触发中断时,处理器会根据中断号查找中断向量,跳转到对应的ISR执行。这个过程涉及到硬件和操作系统的协作,比如中断控制器的配置和向量的初始化。 然后,我需要考虑如何将这些信息结构化地呈现给用户。可能需要分点解释中断号的作用、向量的结构,以及它们在嵌入式编程中的实际应用。同时,结合用户提供的引用内容,比如引用[1]提到的中断/异常机制是计算机系统的核心,说明硬件和软件如何协同工作,这里可以强调中断号作为硬件与软件交互的桥梁。 用户提供的引用[2]提到了调度程序切换上下文和用户模式,这可能与中断处理后的上下文切换有关。虽然主要讨论进程调度,但可以指出中断处理完毕后,如何通过调度器恢复程序执行,这也涉及到中断处理的全流程。 另外,引用[3]提到状态机实现工具,虽然不直接相关,但可能在复杂的中断处理逻辑中有应用,比如使用状态机管理多个中断源的情况,但暂时可以不深入这部分,除非用户进一步询问。 还需要注意用户提到的LaTeX格式要求,确保技术术语和公式正确使用,例如中断号与向量索引的关系可以用数学达式示,比如用$vector\_table[IRQ\_number]$来说明访问方式。 用户可能还需要具体的代码示例,比如在STM32或AVR微控制器中如何配置中断向量,或者如何注册中断处理函数。需要确保代码示例正确,并符合常见的嵌入式编程实践。 最后,生成的相关问题需要围绕用户查询的核心,可能涉及配置步骤、常见问题、优化方法等,帮助用户深入理解中断处理的各个方面。</think>### 模块中断号与中断向量详解 在嵌入式系统编程中,**模块中断号**与**中断向量**是中断处理机制的核心组成部分,其协作流程如下: 1. **模块中断号 (Interrupt Number)** - 定义:硬件模块(如定时器、UART、GPIO等)的唯一中断标识符,通常由芯片手册规定。 - 作用:标识中断源,例如STM32中定时器TIM2的中断号可能为$IRQ\_TIM2=28$。 - 配置:通过寄存器设置中断优先级和使能状态[^1]。 2. **中断向量 (Interrupt Vector Table)** - 结构:存储中断服务程序(ISR)入口地址的数组,索引由中断号决定。数学示为: $$vector\_table[IRQ\_number] = ISR\_address$$ - 初始化:系统启动时加载到固定内存地址(如ARM Cortex-M的0x00000000)[^1]。 3. **中断处理流程** - 硬件触发中断后,CPU根据中断号索引向量,跳转至对应ISR。 - ISR执行完毕后,通过上下文切换恢复原程序流程[^2]。 ### 嵌入式编程中的实现示例 ```c // STM32中断向量定义(简化版) void (*const vector_table[])(void) = { [IRQ_TIM2] = TIM2_IRQHandler, // 定时器2中断服务程序 [IRQ_USART1] = USART1_IRQHandler // 串口1中断服务程序 }; // 中断服务函数示例 void TIM2_IRQHandler(void) { // 清除中断标志 TIM2->SR &= ~TIM_SR_UIF; // 处理定时器溢出事件 } ``` ### 关键问题与优化 - **向量重定位**:可通过修改$VTOR$寄存器实现动态加载,适用于RTOS多任务环境。 - **中断嵌套**:需配置优先级分组(如ARM的NVIC),数学优先级计算为: $$priority = (group\_priority << sub\_priority\_bits) | sub\_priority$$ - **性能影响**:过长ISR会阻塞低优先级中断,可通过"中断下半部"(Bottom Half)拆分处理[^1][^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值