GUI与CUI

在GUI之前,应用程序与用户的交互多是通过控制台界面(Console User Interface, CUI)完成的
图形用户界面(Graphic User Interface, GUI)的操作系统开始在中国流形应该是从Windows95正式发布开始

消息驱动

Windows GUI运行的机理是使用消息(Message)来驱使程序向前运行

  • 消息的主要来源是用户的操作,比如单机鼠标、按下按钮,都会产生消息
  • 消息又会被Windows翻译并送达目标程序然后被程序所处理

这种居于操作系统底层的机理势必深刻地影响到应用软件开发的方法论

为了能编写出Windows上运行的GUI程序,各种开发方法论也必须跟从这种“消息驱动程序”的基本原理
正是沿着这条路发展,才有了后面的技术

  • Windows API开发的纯消息驱动
  • MFC等C++类库的消息驱动
  • 从Visual Basic开始到.NET Framework的事件驱动

总之,程序是被来自UI的事件(即封装过的消息)驱使向前的,简称“消息驱动”或“事件驱动”
因为消息和事件大都来自于UI,所以统称它们为“UI驱动程序”

UI相关的设计模式

消息驱动或事件驱动本身并没有错,但是从更高的层次上来看,使用“UI驱动程序”开发程序则是“为了GUI而GUI”、单纯地位了实现程序的GUI化

  • 实际上着已经背离了程序的本质——数据加算法,同时迫使程序员把很多精力放在了实现UI的编程上
  • 随着程序UI的日趋复杂,UI层面上的代码与用于处理数据的逻辑代码页渐渐纠缠在一起变得难以维护

为了避免这样的问题,程序员们总结出了MVC和MVP等诸多设计模式来把UI相关的代码与数据逻辑相关的代码分开

应用程序的三层结构

一般情况下,应用程序会有三层结构,即数据存储层、数据处理层和数据展示层

  • 存储层相当于一个城市的仓储区,由数据库和文件系统构成
  • 处理层更正确的称呼应该是逻辑层,与业务逻辑相关、用于加工处理数据的算法都集中在这里,这一层相当于城市的工业区
  • 展示层的功能是把加工后的数据通过可视的界面展示给用户或者通过其他种类的接口展示给别的应用程序,还需要收集用户的操作、把它们反馈给逻辑层,所以这一层相当于城市的港口区

程序的本质是数据加算法,而且数据会在存储、逻辑和展示三个层之间流通,所以站在数据的角度来看,这三层都很重要,但算法在程序中的分布就不均匀了,对于一个三层结构的程序来说,算法一般分布在这几处
A. 数据库内部
B. 读取和写回数据
C. 业务逻辑
D. 数据展示
E. 界面与逻辑的交互

其中:

  • A、B两个部分的算法一般都非常稳定,不会轻易去改动,复用性也很高;
  • C处于客户端需求关系最紧密、最复杂,变动也最大,大多数算法都集中在这里
  • D、E两层负责UI与逻辑的交互,也占有一定的算法

显然C部分是程序的核心、是开发的重中之重,所以我们应该把精力集中在C部分

然而,D、E两个部分却是经常成为麻烦的来源。

  • 这两部分都与逻辑层紧密相关,一不小心就有可能把本来该放在逻辑层里的算法写进这两部分(所以才有了MVC、MVP等模式来避免这种情况出现)
  • 这两个部分以消息或事件的方式与逻辑层沟通,一旦出现同一个数据需要在多处展示/修改时,用于同步的代码就会错中复杂
  • D、E本应是互逆的一对儿,但却需要分开来写——显示数据写一个算法、修改数据又是一个算法

总之,导致的结果是D、E两个部分会占去一部分算法,搞不好还会牵扯不少精力

问题的根源就在于逻辑层与展示层的地位不固定

  • 当实现客户需求的时候,逻辑层的确处在中心地位
  • 但到了实现UI交互的时候,展现层又处于中心地位

有很多UI框架(如WPF等)都专注于展示层技术,在深层次上帮助程序员把思维的重心固定在逻辑层,让展示层永远处理逻辑层的从属地位。

参考文章

  1. 《深入浅出WPF》第六章 深入浅出Binding