技术开发 频道

浅谈企业应用架构

    (三)应用问题

    1.事务管理

    A. 成熟的事务技术:如数据库;

    B. 合理的并发设计控制;

    C. 完整的业务日志;这也是解决业务回退的主要手段;

    D. 辅助的数据校验能力;

    并发设计控制和完整的业务日志,是架构设计中保障数据一致性主要着力点。并发设计控制,需要结合业务,通过悲观锁定来保障。

    而业务日志的获取则面临着诸多困难,主要是业务事务和物理事务的不一致性(即一个业务事务可能横跨多个物理事务,也可能一个物理事务包括多个业务事务);业务日志控制层面有两个:应用系统或基础设计;通过应用系统编码控制,则不可避免的提高了应用系统开发和测试的成本;通过基础设施控制,有助于减低成本,但提高基础设施的设计成本;

    2.并发处理

    分析业务所涉及的并发场景,制定相应的原则和方法,并合理选用现有的并发处理框架,进行一定程度的剪裁,通过框架支持和简化这些原则和方法的实践。

    3.系统分解

    基于应用的层面的分解,有多个纬度,包括:业务抽象度,业务任务,业务产品线,以及业务领域等等。

    4.集成能力

    软件开发的适应性在于分解粒度的大小,而分解粒度大小取决于集成能力。

    1)依赖管理

    在技术的角度看,软件系统是一个存在大量依赖关系的对象系统。其中包括了两种依赖:

    (1)业务代码的对象依赖;比如调用一个工厂类创建一个对象。

    (2)业务代码的环境依赖;它可能依赖于一个Web环境(读写Request和Response流),数据库系统(读写数据记录),文件系统和网络系统等。

    不幸的事是这种代码量占据了大量的开发工作。重复的开发工作(对象或者数据的依赖关系维护工作)减低了开发效率和系统适应变化的能力。

    而这样复杂依赖关系也给软件的测试带来了相当大的困难需要搭建足够的依赖环境(如一台Web服务器和数据库服务器),甚至是硬调试。

    于是就有了采用第三方代码来完成依赖关系维护工作的思路,所谓的依赖注入。业务对象出现Spring等著名框架

    动态代理技术则解决了提供支撑环境封装的问题。比如提供网络访问能力(如RMI,URL和Web Services),文件访问能力(如xml、property文件读写)。

    由于企业开发中数据库技术的应用不可避免,因而ORM框架的出现还有特别的意义,在它的支撑下,核心业务西可以严格区别领域逻辑和业务逻辑,而这在以前是做不到的。

    AOP开发的出现解决了面向对象下的横向组织关系。从一定程度上看,AOP可以看作是另一种依赖关系,可以另外依赖注入来实现。当然也可以采用编程实现。

    2)数据对象

    说起集成,就不得不提到一种类型的对象存在——VO对象。

    VO对象是为了集成而存在的;其意义是:1. 保护系统的信息边界,提供一种结构可以使其它系统或者组件通过编码方式获取系统内信息的方式;2. 保护系统的事务边界,领域对象技术上携带着持久化信息,通过VO可以屏蔽得以屏蔽。常见的VO对象存在于Web层和Domain层。

    因此,VO对象的存在只是为了集成而存在,其是否存在的取决于两个方面1. 集成的设计结构;2. 框架的两个能力——对象路径访问能力以及事务边界管理。

    Domain层VO对象,通常是用于不同领域组件间的交互,但随着架构的改进,集成代码独立存在而不再嵌入到组件内部,组件的边界问题保护不复存在;更进一步的是,框架提供自动化的接口适配映射能力的增强。因而VO对象失去存在的意义。

    Web层VO对象,以SWF为例,早在SWF 1.x时代,框架就提供了丰富的对象路径访问能力,但其Web交互是典型的MVC2方式,事务边界在view的render前关闭,因而导致需要特定的VO对象来避免持久化信息问题;而SWF 2.x时代,view的render是在事务边界内,VO不再需要。

    系统设计是一种结构化过程,逻辑和数据被分解和集成到系统的各个部分;在运行期,真正重要的是结构化路径访问能力,换句话说重要的是结构化后的路径,而实际用何种数据结构其实不重要。

    可以使用数据树Data Tree形式,提供扁平化的数据访问能力,是一种较好的开发方式,极大的提升了开发效率。Spring Web Flow以及其它框架广泛的运用EL提供统一的表达式访问数据,也大大降低了开发成本。

    3)事件机制

    事件机制应用非常广泛,是很重要的集成手段。事件机制的优势在于其提供了松散耦合而带来的扩展能力。基于传统事件模式,可以扩展提供同步/异步,事务隔离等额外控制能力。

    4)组件设计

    一个组件包括了API和SPI,其中API是用于客户方编程,SPI用于服务方编程(属于框架回调)。无论是API和SPI都是该组件所有,体现了一个组件自身的完备性。其与其它组件依赖通过集成模块完成,依赖解藕。

    组件的设计还分层次,上层组件的逻辑依赖下层组件,上层组件直接访问下层组件的服务和模型,保持单向依赖有助于降低开发和维护成本。而平级组件,由于组件的替换可能性大,因而保障组件边界完整性尤为重要。

    接口的实现是关键。面临的问题是,在开发初期需求不确定和经验不足的情况下,接口的设计不尽合理,导致需求变动后,所进行的修改将影响三个方面,接口、接口实现对象和测试用例。工作量将可能很大。特别是在并行开发过程中,一个通讯接口的变化将可能引起很大连锁反应,导致其他成员不得不停下手上的工作。

    因而在实际开发中需要做个权衡。不同模块的通讯接口应该由团队成员共同负责,一旦接口变化,接口实现成员应该提供相应的假实现。而模块内部可以由开发人员自行设计,可以在初期不提供接口和简单的测试用例,在项目具有一定稳定性后,利用重构实现接口和完整的测试用例。

    有效定位系统错误。尤其在组件化和分层化,以及其它开发手段混合运用情况下。例如,A,B,C。由于C引起的错误导致A错误是很难查的。代价很高。

    5)胶水层

    胶水层代码属于集成范畴。它是系统开发中不可避免的。胶水层代码的存在增加了设计、开发和测试的成本。因尽量减少胶水层代码的人工开发。

    胶水层代码有两种类型:一是适配器,二是开发模式。

    适配器对于集成来说并不陌生。适配器从用途上分可以分为两种:业务适配和技术适配。业务适配是指处理应用程序接口的适配调用,消除应用程序的耦合度;技术适配是指处理应用程序和技术框架上,消除技术框架的耦合度。

    开发模式是指基础平台对于应用开发的支持减少无效代码,例如采用ORM系统(如Hibernate)以及有状态的Web层框架(如Seam和SWF)可以有效减少应用系统处理数据(对象)状态;以及各种元数据的识别和增强。

    6)集成阶段

    根据阶段分为:设计时, 编译(加载)时和运行时。设计时是由人工编码,通常就是一些特定业务代码,完成集成工作;编译时集成工作通常指配置文件,由程序员提供,但不需要编码工作;而运行时指通过指定元数据,由框架运行时解析;

    5.部署方式

    部署有两种:本地部署和分布式部署。

    分布式部署会带来额外的问题。如果支持分布式部署,有两种方案:

    (1)前后端分离方案

    传统EJB方案就是此种。面临的问题和风险:

    a) 部署成本,即分布部署带来开发成本;

    包括:分布式调用;分布式事务管理;开发模式(即上下文的传递)。

    b) 运行成本,即分布式数据传输性能问题;

    (2)采用Portal或类似技术

    (四)设计问题

    设计文档依然有用,采用Color UML有助于阅读。

    面向对象提供各种关系的表达能力:关联,依赖,集成,组合等;类似于数据库表关系,但是更强烈。在设计时需要注意表现。

    新的开发方式,应该可以通过代码记录分析设计的成果,形成系统中一个稳定的可发展的抽象层次代码,而开发实现则继承或者适配该抽象层次,最终保证系统可运行性。

    这样知识层面的分析设计可以有效贯彻发展,而操作层面的开发实现可以关注于实现过程的工具和手段。这样就可以确保设计是做正确的事,而开发过程提供各种框架工具则把事做更有效率。

0
相关文章