写点什么

表现层模式新探

  • 2009-01-30
  • 本文字数:2961 字

    阅读完需:约 10 分钟

简介

多年来, 由于各种原因,IT 界已经习惯了一些很离谱的设计模式,这恰恰成为全新时代创建优秀分布式应用的巨大障碍,我们由此有必要更新对目前表现层实现技术的一些看法。本文中,我们想要表述的观点是由 web 应用表现的整个瘦客户端其实很傻,应该摒弃。我们这么认为的原因,那还得从九十年代中期,web 刚刚兴起的时候开始说起。

历史

随着 Web 的一夜兴起,几乎同时出现了两种背道相驰的开发: (1)作为无处不在的客户端“应用平台”成就了浏览器的绝对重要性,应用因此很容易部署;(2)各商家间的分裂剥夺了平台原本拥有的发展潜能。这第二条,说得直接点就是 Netscape 和 Microsoft 之间的浏览器之战。这场著名的“战役”导致的最后结果是两个产品系列在显示 web 页面、执行 JavaScript 代码的时候所采用的方式大相径。web 应用要么只能在这个产品上运行,要么只能在另一个产品上运行,这样的事情很平常,但着实让人气愤。一方面,越来越多的应用需要采用 Web 方式向用户发布;另一方面,发布应用必须的平台却是如此不可靠。这时候,企业该怎么办?

最常见的决策是仅依赖浏览器那些非常有限的基本功能——显示格式简单的 web 页面、链接、提交表单等,而表现层的逻辑则转移到服务供应商能够控制的系统部分——Web 服务器。很多服务器端的 web 框架开始提供一些功能来管理复杂的组合业务逻辑以及单一平台上的表现逻辑。Struts 大概是这些框架中最早的一个成功案例。如今,保守点说,起码有 50 多个类似的框架,几乎每个框架都表示自己拥有“前辈”所没有的特点。

然而,让我们坦率的来看待这些框架所带来的影响。尽管服务器端的表现逻辑都能够借助这些框架而更有条不紊、更合理,但它们无非都是在为保持一个不完美的系统而服务。表现层的结构较为松散,整个表现逻辑由于额外原因不得不分割为浏览器和 web 服务器两部分来负责,而这个额外原因与成熟的构架毫不沾边。同时,表现逻辑和服务器端业务逻辑间需要紧密的耦合。尤其是当前的 web 框架在 server 上通过各种服务器端模块、配置文件、注解或者类似工具来创建客户端,本该非常直接的创建工作无形中变得非常复杂。如今,web 框架不仅没什么用处,而且即使是把它们当作系统的组件都很大程度上阻碍我们创建更好的应用。

新型实现技巧

最近,起码有三种开发方式是上文提到的历史的突破。

  1. 一个“老”原则的重新兴起,或者说是“面向服务构架(SOA)”的流行,间接推动了表现层外观的改变。正如其所定义,SOA 更合理地组织业务逻辑,而且为实现整个逻辑提供统一接口。建立好构架的基础是囊括整个应用各个方面的各个互不相关的离散层,用户接口(UI)借助 SOA 能够实现真正的表现层构架。这样的表现层没有业务逻辑,只有业务服务的客户。
  2. 由于浏览器分裂造成的前十年 web 应用无法跨浏览器的“创伤”已经很大程度愈合了。几乎所有浏览器现在都符合工业标准。因此,开发不用再停留在尽量减小对 “古怪”平台依赖的策略上。我们完全可以把所有表现逻辑布置在浏览器平台上,这本该就是它们应该呆的地方,而且现在也不用担心浏览器供应商的不同实现方式,各种浏览器都能够按照你所期望的方式运行。
  3. XML 已经成为个系统间数据交互的通用语。在我们看来,SOA 某种程度上主要就是 XML 文档交换的设计,其次是探究如何实现文档交换。已经有很多非常好的工具来处理 XML,还有很多新兴语言(尤其是脚本语言)都开始将 XML 当作原生数据类型来处理,XML 的使用因此更为简便。由于新工具,SOA 类型系统的创建尤为自然。

所有这些开发其实都受益于同一个构架模型——SOFEA(Service-Oriented Front-End 构架)。有趣的是,很早之前的富客户样式,在经历了瘦客户端和 web 模式大行其道之时黯然失色之后,如今又重新映入人们的眼帘,而且指向更优秀的构架发展方向。

新模式的基本原则是区分表现层和业务逻辑所关注的问题。后者和 SOA 的原则完全一致,表现层因此必须和面向服务的业务层通过正确定义的服务接口而实现兼容。假如仔细研究 SOA 在不同构架的领域(无论是市场部、财务部这样的应用领域还是构架“层”这样的技术领域)之间交换设计正确的结构化数据的话,就会发现表现层根本没有理由脱离前面提到的那些原则。

实现兼容性的重要因素之一是保证数据在应用端到端间完整传递。也就是说,要使用 XML 文档形式来说明 XML,XML 文档可以应用于当前流行的任何 service 形式——比方说,SOAP/WS-* 和 REST。

新模式的元素

上面这张图表现的是构架中主要的物理组件和逻辑处理件。应用容器(Application Container)通常指的是客户端应用运行平台。需要注意的是它绝对不是服务器端组件。应用(Application)指代的是在该平台上运行的代码。应用也不是应用容器的组成部分。

应用的代码存储在应用平台之外,代码在需要的时候及时加载到平台上。下载服务器(Download Server)组件就负责为客户平台提供应用,因此可以在应用运行之前将其安装到本地。服务接口(Service Interface)是服务层的标准接口,它支持应用表现层和业务逻辑层间交换 XML 文档需采用的简易机制。

客户端有三个基本处理过程。下载应用(Application Download)是指在应用运行之前将应用下载到应用容器的过程。通常来说,这一过程只需一次完成,但有时候也可能采用“懒”机制,界面则只在调用的时候才从下载服务器上下载。在后面这种“懒”下载机制中,系统的行为和由服务器端 web 框架驱动界面流程的传统 web 应用不同,而是由按需下载界面的客户应用来领导整个流程。表现流(Presentation Flow)是指将界面(或其它特定方式的媒介)展示给用户的逻辑。数据交互(Data Interchange)则是表现层和服务层之间的数据(XML 格式和符合 Schema 的数据)交换。

基础原理

该模型的核心主题是分解正交的相关方面。一直以来都有人在提这样的要求,但从来有实现,而其中的障碍就是前文讲述的客户平台的限制。现在,应用的创建形势终于向本该的方向发展。表现层变得越来越小、更加紧凑、更容易理解,也更容易维护,因为业务逻辑已经完全从表现层中剥除。服务端也同时受益匪浅,因为它也不再与表现层逻辑有任何牵扯。

新模式所蕴含的意义

  • 精简的构架模型包含了表现层和业务逻辑层无阻抗失配的完美集成。
  • “web 服务器”的角色(首次)更为合理。
  • 支持 MVC 这个表现层最自然的设计模式。
  • 保证应用间端对端数据的完整;统一了“瘦客户”和“富客户”模型。
  • 支持无论是基于 SOAP 还是 REST 的服务。
  • 服务器运行更加轻便,因为其不需再负累表现层相关逻辑。
  • 降低了创建同组业务服务的多用户接口的开销。
  • 复用表现层模块的压力骤降,如果业务层设计合理的话,从表现层调用正确的服务就能实现足够的复用。

技术案例

Ajax 框架(Dojo、jQuery、Ext 等), GWT、 TIBCO GI、XForms、Mozilla XUL、Microsoft Silverlight/XAML、Java WebStart、JavaFX Script、Adobe Flex、OpenLaszlo 等。

结论

本文提到的模式没有引进很多新的技术或是概念,却已足够说明陈旧的根深蒂固的折衷开发模式应该成为历史。我们试着展示的是新技术是如何在原本早应该发展的方向上推进应用的设计和创建。这一模式的发展时代终于来到了。

阅读英文原文: Rationalizing the Presentation Tier


给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。

2009-01-30 21:246221
用户头像

发布了 71 篇内容, 共 23.8 次阅读, 收获喜欢 3 次。

关注

评论

发布
暂无评论
发现更多内容

leetcode 540. Single Element in a Sorted Array 有序数组中的单一元素

okokabcd

LeetCode 查找

【Go实现】实践GoF的23种设计模式:抽象工厂模式

元闰子

Go 设计模式 抽象工厂模式

架构实战营 - 模块 2 作业

Gavin.Yang

FacadePattern-门面模式

梁歪歪 ♚

设计模式

从原理到操作,让你在 Apache APISIX 中代理 Dubbo3 服务更便捷

阿里巴巴中间件

阿里云 开源 云原生 dubbo

SAP UI5 的自动化测试套件页面的开发步骤介绍

汪子熙

JavaScript SAP SAP UI5 5月月更 SAP前端开发

[Day47]-[递归]-基本计算器

方勇(gopher)

递归 LeetCode

DecoratorPattern-装饰者模式

梁歪歪 ♚

设计模式

ProxyPattern-代理模式

梁歪歪 ♚

设计模式

密码学系列之:PEM和PKCS7,PKCS8,PKCS12

程序那些事

密码学 程序那些事 5月月更

软件构建

GalaxyCreater

架构 敏捷 软件设计

跨平台应用开发进阶(十八) :全局异常日志处理方案探究

No Silver Bullet

5月月更 异常日志 处理方案探究

微信朋友圈高性能架构设计

地下地上

架构实战营

Flutter 利用 StreamProvider 一起玩 WebSocket

岛上码农

flutter ios 前端 安卓开发 5月月更

架构实战营模块二作业:微信朋友圈高性能复杂度

融冰

一个程序员眼中的元宇宙

总师

程序员 元宇宙

BuilderPattern-建造者模式

梁歪歪 ♚

设计模式

AdapterPattern-适配器模式

梁歪歪 ♚

设计模式

[go]mongo工具类

林逸民

Go mongo goalng-underscore

[Day48]-[递归]-基本计算器 II

方勇(gopher)

递归 LeetCode

微信朋友圈高性能复杂度分析

Justin1024

一文读懂AQUANEE的开创性特点与未来

小哈区块

如何提高技术部的信任值

石云升

项目管理 职场经验 5月月更 跨部门沟通

# 继续前行github star突破8k即时通讯IM开源项目OpenIM版本发布计划

Geek_1ef48b

SpringCloud Alibaba Sentinel 限流详解

牧小农

sentinel springcloudAlibaba

Docker下RabbitMQ四部曲之四:高可用实战

程序员欣宸

Java Docker Docker-compose RabbitMQ 5月月更

Feign 共享登录信息进行请求

Java Feign

SDN系统方法 | 1. 概述

俞凡

架构 网络 sdn SDN系统方法

在操作系统这条赛道上,为什么Laxcus和Windows、MacOS不一样

LAXCUS分布式操作系统

大数据 容器 虚拟化 并行计算 分布式操作系统

表现层模式新探_SOA_Peter Svensson_InfoQ精选文章