DDE与Serialization,GUI设计中的三层结构

最近我正在用wxWidget做一个主成分分析的程序。wxWidget我只用过不多几次,唯一的感觉就是和MFC太像了。

这个程序的主UI部分是一个data Grid。我初始的做法是直接在需要读取数据的时候从这个widget中读字符串然后转换,计算完毕后再转换为字符串输出。

第二次的时候,我改变了做法。我把原来的处理函数分为3部分,数据处理、TransferDataFromWindow、TransferDataToWindow。这样的代价是多用了2个循环降低了效率,并为this增加了一个成员变量,好处是程序结构一下子就变得特别清晰。

我发现这有点类似于网页设计,努力将数据显示与数据本身相分离。它使得一部分程序员可以专注于GUI设计或数据处理。负责数据处理的程序员可以完全不知道这个程序是否有GUI,而负责GUI设计的可以完全不懂算法。这大概就是软件工程上常说的,降低耦合性。

在使用DDE之前我主要的犹豫就是如果这样,那么我必须为每个控件增加一个成员变量以把数据binding上去。这就引起了一个问题,什么时候应该增加成员变量?增加一个成员变量,可以使得成员函数少一个参数,数据在成员函数中传递起来更简洁,但是同时,成员变量与全局变量一样,是魔鬼。它的生命周期太长,以至于我们总是怀疑它现在是否正处在正确的状态。

在GUI设计中,这个原则可以被简述之,成员变量的使用须遵守最少化原则,成员变量仅仅是用来保存该实例的状态。如果该数据不需要在两个状态之间传递,那么就应该存储在类体中。例如。窗体不断刷新,没有接到任何信号,这是一个状态。button1按下并处理这个事件的时候这又是一个状态,button2按下并处理这个事件的时候这又是一个状态,如果一个变量需要从一个事件传递到另一个事件,那么,就需要设置为成员变量,反之,不需要。

(fp的一个原则就是尽量不使用mutable variable,但是fp的一个缺点也是状态机实现起来很复杂。)

类似于Java程序员常论的MVC,我们也可以把GUI分成三层,显示层,数据层,持久化层。显示层/数据层
即我们常说的document/view,文档视图模型,中间靠DDE进行连接。而数据层/持久化层,it's none of GUI
programmer's bussiness.如果不采用文档视图的方式,那么如果要将窗体中的数据持久化,简直是恶梦。

DDE也有缺点,效率低下,例如我们通常需要做的只是部分刷新。尤其是在有大量数据需要显示的时候,如果只为了获取一个textbox的value而要对整个窗体进行一次数据刷新,(例如我现在所面临的),那么代价也太大了。所幸的是wxWidget引入了Validator的概念,为每个control bind 一个 Validator,Validator的作用不只是数据验证,同样也担任着数据交换的作用。

此博客中的热门博文

少写代码,多读别人写的代码

在windows下使用llvm+clang

tensorflow distributed runtime初窥