一点小感受:界面和程序的分离

1 Windows桌面程序,界面和程序是源码级混合

Windows系统下的GUI程序,界面(GUI)与程序其他部分逻辑上是分离的,但是源码上直接交互,界面功能直接通过调用Win32 API来实现。

例:CreateWindow()。

写Windows桌面程序,必须调用GUI32.dll导出的API,无他可选。

甚至线程模型很多功能都和GUI窗口绑定到了一起,如消息队列。

2 Linux程序,界面和程序是通过协议通信

2.1 CUI程序和文本终端通过终端协议交互

对于CUI的程序来说,文本终端是通过标准的终端协议(行行程协议)来提供接口功能的。文本终端和主机完全可以运行在不同架构的机器上,只要彼此都遵守同样的终端通信协议,程序和终端就能完美交互,而不受通信媒介的限制。

正因为如此,才使得SSH等远程终端等方便的远程连接方式很容易被理解和实现。

这种彻底的分离,带来了设计上的完美感。

让每一个程序员都去了解使用终端协议是非常费时(个人认为非常有意义)的事情,而且更可怕的是终端协议并不是只有一个,各终端设备厂家有自己的协议扩展,如VT100。

为了便于使用,人们开发了封装终端协议的函数库。最基本的就是C标准函数库里的printf(),scanf()了。功能更强大的就是著名的curses库了。当我们编写Linux程序使用这些库函数的时候,最好能想到其底下支撑它的终端协议。

2.2 GUI程序和XWindow Server通过X协议交互

与文本终端的概念一脉相承,XWindow提供了图形终端的功能。程序通过标准的X协议与图形终端XWindow Server交互。

图形终端的功能要比文本终端强大的多,也复杂很多,其通信数据量更是大幅增加。这些都导致了X协议的复杂性。所以直接通过X协议来调用GUI功能,显然过于繁琐。于是,人们开发出了封装X协议的XLib库,为了更加简单的使用,基于XLib库有开发出了各种高级封装库,如GTK,Qt等。

当我们使用这些库函数的时候,别忘了其底层最终是使用X协议与图形终端进行了通信。

2.3 直接操作的显卡不是终端

Linux支持直接操作显卡设备,特别是对framebuffer的支持使得直接读写显卡非常方便。然而这样的读写与界面的操作是两个完全不同的概念。Linux程序的界面就是终端,至于终端如何利用显卡那是终端的具体实现,对Linux程序不可见。就算是最简单的printf(),Linux程序也是写到终端上去,而不是直接写到显卡上。对于本地终端来说,终端和程序运行于同一台机器上,很容易让人混淆终端和显卡设备。要记住,本地终端只是终端中特殊的一种,理解终端概念的时候,最好想象远程终端的情形。

3 Web程序,界面(HTML)和后端程序通过标准HTTP协议进行通信

虽然Web程序也是图形界面程序,但是其后端程序对界面的控制粒度很大,而且程序不能主动发起到界面的通信,这些限制导致HTTP协议非常简单,通信数据量也很小。

越简单的事情往往越容易取得成功,Web程序最终取得了辉煌,成为了程序模型的主流,越来越多的桌面程序被同功能的Web版本程序取代。

当然了,由于Web后端程序对界面的操作功能有限,所以大量的图形图像程序不会被Web取代。

4 分离还是混合?

界面和程序逻辑是分离好,还是混合好?逻辑上,界面功能算是一个非常成熟独立的模块,从模块化设计的角度来说,分离是最完美的选择。然而,对于图形密集型程序和频繁交互的程序(比如Photoshop,3D Max)来说,界面功能占据了程序逻辑的大部分,此时交互的流畅性就成为关键。界面分离的程序交互效率必然受到影响,所以Windows和Mac的图形界面交互流畅度要大大高于XWindow。

然而毕竟图形密集和交互密集型程序只占据软件市场的很小一部分,对于广大的其他类型程序来说,界面的分离无疑会带来设计上的美感和简洁,运行上的稳定。看看大多数的服务器、嵌入式设备吧。

再者,硬件技术的提升往往比软件设计的改良更加容易,所以随着硬件水平的提高,界面的分离必将是最终的胜利者。

5 协议还是API?

程序不同模块的交互方式按照耦合程度由高到底可以分为:(1)源代码级别混合;(2)API函数;(3)协议。

源代码级别混合指的是彼此暴露数据结构实现细节,除非是非常简单的程序,否则这种设计基本是不合适的;

API函数级别,指的是把一个模块当成库来设计,对外之暴露有限的函数,使用透明数据结构指针作为函数参数,所有模块必须运行与同一个机器,同一个进程。

协议级别,指的是对外暴露通信标准,模块间通过标准的协议来交互。此时,不同模块可以运行于不同机器。

在(2)和(3)之间还有一个多进程程序设计的方式,各个模块被当作独立的进程来运行,模块之间通过本机IPC进行通信。

程序设计时,要根据程序的规模,具体的业务逻辑、扩展需求来确定模块间交互的方式。

时间: 2024-12-19 14:27:34

一点小感受:界面和程序的分离的相关文章

程序开发的一点小总结

程序开发的一点小总结, 给要学习一门新语言的朋友一些帮助, :P 1.多项条件下的处理 第一种方法: 每个需要执行A函数的条件下都写一边A函数调用, 这种方式也是最中规中矩的写法, 代码相对臃肿, 如果A有任何变动, 就要修改多处, 这种代码块写多了, 容易漏掉 if(b==1) a() else if(b==2) else if(b==3) a() else a() 第二种写法: 在B条件筛选前, 创建一个临变量布尔c, 用来监控需要A函数需要的条件, 需要就为true, 不需要就不写(默认初

Java 并发编程之图形界面应用程序及死锁问题

不知道为什么这本书还要讲一个界面应用程序,Java的界面做的很糟糕,效率低下,而且界面是java的弱项,可能是因为这里边是有一些并发编程的知识吧. 为什么GUI是单线程的 无论是Swing还是AWT都是单线程的.但它不仅限于在java中,在Qt,NexiStep,macOs CoCoa X windows以及其它环境中的GUI框架都是单线程的,许多人都曾经尝试编写多线程的GUI框架,但最终都由于竞态条件和死锁导致的稳定性问题而又重新回到单线程的事件队列模型:采用一个专门的线程从队列中抽取事件,并

新闻发布的一点小总结

经过一段时间的学习,完成了新闻发布的基础功能,进行一点小总结,方便日后回顾.下面是我的一点小总结,不足之处请勿见笑... 我们想要完成一个新闻发布,首先要使其能够成功发布,并且让它能够实现添加.删除.修改.查询.上传.下载等功能.我们还调用AJAX功能查看输出为XML.JSON格式的新闻内容.为完成以上功能,我们首先要进行jdk.tomcat.eclipse的安装和配置.1.各软件的安装和配置1.1.jdk的安装和配置: 1.1.1.下载jdk:下载地址:http://www.oracle.co

8-22发现的一点小问题(在“引用”上出的问题)

今天写程序是发现了一点小纰漏: 程序的大体结构如下: Public class act extends Activity { //保存数据的list Private ArrayList<T> listInAct = null; Private ListView listView = null; } Public void onCreate(Bundle b){ listInAct = new ArrayList<T>(); .............................

SPComm的一点小诀窍 spcomm的问题导致数据丢失 0x11与0x13错误

最近几天完成了BiasDAC的程序编写.调试的过程还算比较顺利,除了几个有点bt的小问题.其中一个困扰了我两三天的时间,今天上午终于将其解决. 由于BiasDAC是用RS232 Serial Port通信的,延用之前的程序,使用了Delphi的SPComm控件.在之前的使用中,SPComm控件一直工作正常,使用的是一般的string进行消息的传递. 而BiasDAC由于通信协议的限制,消息的发送使用的是hex方式,会用到从0x00到0xFF所有的这些字符.在调试中发现,发送0x11和0x13之后

关于win8开发的一点小总结

我今天做画面的时候,发现了一点小问题. 我在xmal文件里面加了一个CheckBox控件,设置IsChecked属性为True,并添加了Checked事件.Checked事件里面有对另外一个TextBox的访问. 这时候我运转程序,它会先走构造方法的InitializeComponent方法,然后就直接走到Checked事件,这时候可以看到TextBox是个null值,也就是说它还没被初期化. 我的理解是InitializeComponent方法先初期化CheckBox,当初期化它的IsChec

关于PHP魔术方法__call的一点小发现

好久没有上博客园写文章了,今晚终于有点空了,就来写一下昨天的一点小发现. 我自己所知,C++,Java的面向对象都有多态的特点,而PHP没有,但PHP可以通过继承链方法的重写来实现多态的属性.而魔术方法会在特定情况下被触发,我们也可以对其进行重写. ---------------------------------------------------------------------------------------------------------摘抄开始----------------

使用PyQt4写界面后台程序方法总结

使用PyQt4编写界面后台程序的方法总结 一.怎么建立多线程 界面程序如果有稍微耗时一点的任务如果不使用多线程就会界面卡死,所以大多数情况会使用到多线程.PyQt4自己有多线程的机制,可以派生多线程类然后生成多线程实例.代码如下: 1 form PyQt4.QtCore import * 2 3 class MyThread(QThread): 4 def __init__(self,func,args): 5 super(MyThread,self).__init__() 6 self.fun

关于学习python的一点小建议

Python是最容易入门的编程语言,没有之一.如果初学者接触的第一门语言是C或者C++,对他们来说最难的不是语法,而是容易出现内存泄漏.指针等问题.有时候排查这些问题对初学者的打击很大,尤其是没掌握排查BUG技巧时. 如果初学者接触的第一门语言是Python,学习曲线则会平滑得多,掌握一些基本语法和Python内置的数据结构,已经可以上手写一些小工具或者小型应用.这对初学者来说,非常重要.因为学习的过程是一个突破舒适区的过程,会面临很多痛苦,如果学习过程得不到激励,很容易半途而废,类似我们开玩笑