banner.gif adie's blog
主页 博客 胭脂泪,相留醉,几时重,自是人生长恨水长东
统计
日志总数: 126
评论总数: 122
日志分类
日志归档
最近日志
最近评论
订阅
rss2.gif

atom.gif

google_rss
yc.gif 【技术资料】 阅读 10039 次

UI与逻辑分离设计

2006-12-05 21:32:27
    UI(User Interface) 即用户接口,指计算机程序和用户交互的部分。逻辑则表示程序中完成实际功能的部分。UI 发展到今天,主要分为 GUI 和 CUI 两大主流。GUI 程序简单直观,对用户要求较低。相对于 GUI 方式,CUI 程序通常有更高的效率(在远程控制时尤其如此),能完成更为复杂的功能,能更好的和其他程序交互,但需要用户记住大量的命令和参数,对用户要求较高。基于这些考虑,我们有时往往需要提供 GUI 和 CUI 两种方式的接口,以便于不同层次的用户在不同的情况下使用。

    要提供两种方式的接口,通常需要把 UI 和逻辑部分严格的分开,让不同的 UI 使用同一份逻辑。如若不然,必然会使程序中出现大量的重复代码,造成维护上的困难。关于如何让两种方式的 UI 使用同一份逻辑不在本文的讨论之列,本文主要讨论 UI 和逻辑的分离。

    首先,逻辑部分需要从 UI 中获取消息,并将信息反馈给 UI,所以逻辑层是依赖于 UI 层的:

其次,在 GUI 中,用户可以通过用户界面来调用一段逻辑功能,所以导致 UI 也依赖于逻辑层:

呃,这是一个非常郁闷的循环依赖问题。当然,和所有的循环依赖问题一样,我们可以通过抽象接口的方式来解决这种直接的循环依赖:

不过这种方式给我的感觉象是掩耳盗铃,虽然在技术上消除了循环依赖,但其内部循环依赖的本质并未改变。为了从本质上消除这种循环依赖,我们先来对 UI 的功能进行分类:
    1. 信息输入。这部分包括 GUI 中的 EditBox, CheckBox, Radio, View… 等等;CUI 中的命令行参数,运行时的输入等等;以及都可能有的配置文件,输入文件等等。
    2. 信息反馈。这部分包括 GUI 中的 MessageBox, EditBox, Static, View…等等;CUI 中的 stdout, stderr 等等;以及都可能存在的输出文件等等。 
    3. 命令输入。这部分包括 GUI 中的 Button, Menu, ToolBar… 等等;CUI 中的程序启动,程序运行过程中的 Ctrl+Break 之类的指令,以及一些交互式 CUI 中模拟的命令等等。命令 UI 总体上是反应了一种消息机制,这通常只是 GUI 方式中使用的,CUI 较少使用。
    将 UI 分为三部分之后可以看出,逻辑层是依赖于信息的,命令是依赖于逻辑的,这些依赖关系都是单向的。为此,我们可以将 UI 与逻辑分为三个层次,而不是两个:

这看上去似乎很优美了,但却有些脱离实际。在这种设计中 UI 被分成了两部分,分别位于最上层和最下层,但现实中为了使用户能更好的操作,通常是一组相关功能的信息输入,信息反馈,命令输入放在一起的,它们之间有比较强的关联关系,如果强制把他们分得天各一方将会导致其他的一些问题。

    通过上面的分类可以看出,导致 UI 和逻辑分离复杂化的原因是命令UI,而命令UI是在 GUI 中出现的。我们可以对比 C++ stream 框架和 MFC 的文档视图结构框架来看看其中的区别:C++ stream 可以看作是一个 CUI 中对 UI 与逻辑分离的一个实现,使用的时候只会在逻辑中使用 stream,而不会在 stream 中使用逻辑,这是一种单向依赖,其实现也是十分的简单优美,易于使用。MFC 文档视图结构是在 GUI 中对 UI 与逻辑分离的一个尝试,但在其中文档会用到视图,视图也会用到文档,是一种循环依赖关系,其实现也较为复杂,不易理解,有时仍然会出现逻辑和 UI 绞在一起情况。

▲评论

X 正在回复:
姓 名: 留下更多信息
性 别:
邮 件:
主 页:
Q Q:
来 自:
职 业:
评 论:
验 证:


Valid HTML 4.01 Strict Valid CSS!
Copyleft.A!die Software Studio.ADSS
Power by webmaster@adintr.com