我们在做着表面上看似是对于各种不同应用的开发,其实背后所对应的架构设计都是相对稳定的。在一个好的架构下编程,不仅对于开发人员是一件赏心悦目的事情,更重要的是软件能够表现出一个健康的姿态;而架构设计的不合理,不仅让开发人员受苦受难,
软件本身的生命周期更是受到严重威胁。这里我将针对在微软dotNet平台上做应用开发的系统架构设计做一个粗浅的讨论。
总体设计
表示层
表示层由UI(User Interface)和UI控制逻辑组成。
UI(User Interface)
UI是客户端的用户界面,负责从用户方接收命令,请求,数据,传递给业务层处理,然后将结果呈现出来。根据客户端的不同我们大体将应用程序分为BS(Browser-Server) 浏览器结构,CS(Client-Server)桌面客户端结构。
BS的优点是无需操心客户端,只需要部署维护好服务器即可。CS的优点在于强大的界面交互表达能力。RIA(Rich Internet Application)是为了融合这两种结构优点的一种技术,它依赖在客户端一次性安装一个通用解释器之后即获得强大的界面交互表达能力和无需部署具体客户端的方便性。具体的实现技术很多,例如微软的SmartClient, Avalon; Macromedia的Flex;以JS为基础的Bindows;Ajax等等很多。
UI控制逻辑
UI控制逻辑负责处理UI和业务层之间的数据交互,UI之间状态流程的控制,同时负责简单的数据验证和格式化等功能。具体的说在dotNet事件驱动的编程模型下,UI控制逻辑被自然的实现在了事件函数中,例如PageLoad事件函数,ButtonClick事件函数。在这些事件函数中,主要任务就是做UI控件与业务实体的数据交换与业务调用,但面对大量的数据交换工作量与维护量就成了最大的问题。而在复杂应用的系统中,状态与流程的管理是必须要考虑的因素,它包含了界面与业务两方面。如果不加以封装的直接写在事件函数中将导致业务依赖表示层。下面分别讨论这两个问题。
1.UI与业务实体之间的数据交互
此阶段负责数据交换的业务实体我把它称为DTO(Data Transfer Object),但需要说明的是这里的DTO并不是只包含数据的业务对象,它仍然包含必要的方法是完整的业务实体。处理输入时我们从UI控件的获得数据填入DTO再向下传播,处理输出时用户发出请求业务层会将数据以DTO的形式返出再赋给UI控件展现。因此需要一种方式来自动解决这样的来回赋值问题。Java下Structs的Formbean对此问题提供了一定支持,而遗憾的是dotNet下的不少控件虽然支持数据绑定但仍然没有一个现成完整的解决办法。一种比较简单的方式是自己设计一个Adapter按照某种映射关系来自动处理这
样的绑定,这样的映射关系最好是UI控件与DTO属性的事先命名约定,以此种方式的约
定作为映射关系无需增加任何配置文件和配置工作即可实现。例如你的一个输入人名的Textbox命名为txtUserName,而我的业务实体属性命名为UserName,这样就可以通过字符串的查找来找到对应。
2.状态与流程的管理
复杂业务方面的状态与流程可以通过一些工作流引擎来解决,微软最近独立发布了自己的
工作流引擎有兴趣的朋友可以去看看。一般更多的情况是需要解决界面上状态与流程的管理。耦合再表示层中是不可取的办法。MVC(Model-View-Controller)模式提供了实现这一目标的方法。Controller是整个方案的核心,它是一个流程管理器,来自UI所有的命令与数据经过Controller分发给业务层或其他UI,这样我们可以把流程,权限等逻辑单独封装,例如配置文件中,达到最大化的业务重用。dotNet下MVC的方案并不像Java下有那么多选择,目前有以下几种选择:
微软的UIPAB,它可以处理bs,cs下的流程跳转,可以使得相同的业务系统有
webform和winform不同的展现