23 Presenters and Humble Objects

在第22章中我们介绍了呈现器(Presenter)的概念,呈现器是“简陋对象模式”(Humble Object Pattern)的一种实现形式,该模式有助于我们识别并保护架构边界,事实上上一章所讲的整洁架构中就大量运用了简陋对象模式的实现。简陋对象模式是一种设计模式,最初被提出是为了帮助单元测试人员将难以测试的行为与易于测试的行为分离开,其思路十分简单:把行为拆分为两个模块或类,其中一个模块是“简陋”的,它包含所有难以测试的行为,且被精简到最纯粹的形态,另一个模块则包含从简陋对象中拆分出来的所有可测试行为。例如图形界面(GUI)很难进行单元测试,因为很难编写测试代码去查看屏幕并确认相应元素是否正确展示,然而GUI的大部分行为其实是易于测试的,运用简陋对象模式,我们可以将这两类行为拆分为呈现器(Presenter)和视图(View)两个不同的类。其中视图是难以测试的简陋对象,其代码会被尽可能简化,仅负责将数据填充到GUI中,不会对数据做任何处理;而呈现器是可测试的对象,它的工作是接收来自应用的数据并进行展示格式化,让视图只需将数据直接呈现到屏幕上,比如应用需要在某个字段展示日期时,会传递一个日期对象给呈现器,呈现器会将其格式化为合适的字符串并放入名为视图模型(ViewModel)的简单数据结构中供视图读取;若应用需要在屏幕展示金额,会传递货币对象给呈现器,呈现器会为其设置合适的小数位与货币符号并生成字符串存入视图模型,若负值需要标红,还会在视图模型中设置对应的布尔标记;屏幕上每个按钮的名称、菜单项名称、单选框、复选框、文本框的标识,以及需要展示的数值表格,都会由呈现器处理为字符串、布尔值等存入视图模型,屏幕上所有受应用控制的展示内容,都会在视图模型中以字符串、布尔值或枚举形式呈现,视图除了将数据从视图模型加载到屏幕之外无需做任何其他工作,因此视图是简陋对象。可测试性一直以来都是优秀架构的重要属性,简陋对象模式就是很好的例证,因为将行为拆分为可测试与不可测试部分的过程,通常也定义了一条架构边界,呈现器与视图的边界就是其中之一,除此之外还有很多类似边界。在用例交互器与数据库之间存在数据库网关,这些网关是多态接口,包含应用对数据库执行的所有增删改查操作对应的方法,例如应用需要查询昨日所有登录用户的姓氏,用户网关接口就会提供一个接收日期参数并返回姓氏列表的方法;我们不允许在用例层编写SQL,而是使用具备对应方法的网关接口,这些网关由数据库层的类实现,该实现类就是简陋对象,它仅通过SQL或数据库接口获取每个方法所需数据,与之相对,交互器封装了应用特定的业务规则因此并非简陋对象,但它们是可测试的,因为可以用桩对象或测试替身替换网关。回到数据库相关话题,Hibernate这类ORM框架应该属于哪一层?首先需要明确的是,并不存在真正意义上的对象关系映射器(ORM),原因很简单:对象并非数据结构,至少从使用者的角度来看并非如此,对象的使用者无法访问其私有数据,只能看到公有方法,因此在使用者看来,对象只是一组操作的集合;而数据结构是一组包含公有数据变量且无预设行为的集合,ORM更适合被命名为“数据映射器”,因为它们的作用是从关系型数据库表中读取数据并加载到数据结构中,这类ORM系统理应放在数据库层,事实上,ORM在网关接口与数据库之间构成了另一种简陋对象边界。对于服务交互而言,如果应用需要与其他服务通信,或是对外提供一组服务,简陋对象模式是否也会构建出服务边界?答案是肯定的,应用会将数据加载到简单数据结构中,再通过边界传递给负责格式化数据并发送到外部服务的模块;在输入侧,服务监听器会从服务接口接收数据,将其格式化为应用可用的简单数据结构,再通过服务边界传递给应用。综上,在每一条架构边界处,我们几乎都能找到简陋对象模式的身影,跨边界的通信几乎总会涉及某种简单数据结构,而边界也常常将难以测试的部分与易于测试的部分分离开,在架构边界处使用该模式能够极大提升整个系统的可测试性。

posted @ 2026-03-20 15:42  cyusouyiku  阅读(0)  评论(0)    收藏  举报