作者在 2011-11-27 00:16:16 发布以下内容
本文转载自:“http://blogs.oracle.com/Swing/entry/一般gui系统的三要素”,文章作者对Swing有着独到的开发经验和见解,如对JAVA GUI感兴趣,欢迎大家访问TA的新浪博客(http://blog.sina.com.cn/s/articlelist_1264601020_0_1.html)
使用和研究Swing已经很长时间了,随着对swing理解的加深,觉得自己对一般计算机GUI(图形用户界面, Graphical User Interface)系统的领悟也越来越多,甚至开始觉得自己理解了一些GUI系统的本质。曾在新浪的博客上写过一系列文章,试图从原理到实现上讲述swing体系结构,现在却觉得仍是没能描述清楚,总觉得缺少从一般原理上理解swing架构的感觉。于是觉得应该把平时悟到的关于GUI系统原理的火花整理出来,也许对更清晰地理解swing有所帮助。
一直在思考一个问题,设计一套GUI系统需要考虑那些问题?GUI系统本质定义是什么?经过一番思索,觉得下面整理的句子最能描述GUI系统本质:
在事件驱动下动态地展现数据模型的图形系统。
首先GUI是图形系统,它通过图形设备如显示器等向用户传达信息。其次它传达的是描述特定数据的信息。最后GUI系统是开放动态的系统,使用从外界获得的事件驱动数据模型的变化,并最终由图形系统将变化展现出来。
数据和信息是不同实体,单纯的数据不能表达任何信息,数据是信息的载体,只有在特定上下文中才能由特定规则解释为信息。GUI系统中的图形界面的任务就是将数据解释成用户能理解的信息。然而封闭静态的信息是没有多少价值的,GUI系统还应该是个开放并演化的系统,它应该能获取终端用户和系统的交互事件,处理并改变当前的数据,最后通过图形界面将数据的变化反馈给终端用户。
跑一下题,注意到这个描述显示了GUI系统的MVC特征。MVC最能体现面向对象思想的模式,其三个基本元素分别体现了面向对象思想中的数据、过程和接口的概念。不过在GUI系统中接口具体是指人机接口(图形界面)。 进一步深入,会发现许多事情都是能三元描述的,而这些元素之间或多或少存在一定的映射关系。比如宇宙世界的三个基本元素:物质、空间和时间。可以想像数据是物质的映射,过程是时间的映射,而接口则是空间的映射。
因此GUI系统的三个基本组成要素是:事件、图形绘制和数据模型。深入理解一个GUI系统的关键就是理解GUI系统的三要素的各自工作原理和协作关系。事件和图形绘制往往是一个GUI系统最直观的要素,但数据模型往往由于设计的角度不同,有些模糊,有些清晰。
根据GUI类库在操作系统中的位置,可以分为操作系统态和应用程序态的两大类:
操作系统态的GUI类库是由操作系统直接提供的、运行于系统级的GUI类库。这种系统典型的由Win32 API中的GUI库,以及基于此类库进行一定封装的语言级别的GUI工具,比如MFC(C++封装)和SWT/AWT(Java封装)。这种系统具有优点有:
1. 由于可依赖操作系统对图形界面系统类库的优化,其响应性能相对比较好,并能获得同操作系统一致的外观。
2. 可以通过操作系统同其它应用程序的通信,获得更好的桌面集成度。
其缺点也是明显的:
1. 应用程序向GUI系统传递和转换数据的开销增大,导致复杂组件,如表格和树的数据显示效率不高。由于GUI系统类库和具体应用程序的开发是分离的,操作系统开发者无法穷举应用程序数据结构,因此只能将数据类型标准化、简单化到简单的数据结构。因此当应用程序如果需要将展现复杂的数据结构时,就需要将数据对象分解或转化成标准的数据类型,并通过系统调用传递给组件。这种转化和系统调用在复杂大数据量的组件中会极大的降低性能。举例SWT来说,它需要将java类型转换标准简单类型,并通过JNI调用传递给原生组件。就目前阶段来说,在Windows 上,SWT借助操作系统优化的图形界面库,可以获得比Swing相对较高的界面响应性能,但是在数据展现性能比不上Swing,其原因就在于此。
2. 这种GUI系统缺少对数据模型概念的有力支持,使得面向对象的设计理念需要更高层次的封装,进一步降低系统的性能。比如JFace,它就是在SWT之上进行了进一步封装来提供对应于Swing中的Model概念的。而Swing由于可以控制模型到图形系统的转换,其View和Model不存在数据转换和数据传递的过程,因此Model和View能形成联动,能很容易实现数据绑定,轻易展现复杂的数据对象,并提高数据展现性能。这种灵活性的优点来自于MVC这个模式的灵活运用。因此说Swing比SWT更能体现面向对象的思想,这是其中的原因之一。
3. 这种系统的可扩展性和灵活性不高。由于操作系统提供的类库和应用程序对其的封装是两个分离的系统,因此对于其基本组件的扩展上只能通过有限的方式进行。比如添加事件处理器,在系统绘制完组件之后做额外的修改。但对于系统绘制的部分却无法控制和改变。而由独立GUI系统却具有更大的可扩展性和灵活性。
今天先说到这儿,以后再就这三个要素逐一展开讨论。