分享
 
 
 

一次关于用MVC改进GUI应用开发的讨论

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

昨天临下班前跟猎手讨论了一个技术问题。今天令狐看了,指出这个解决方法治标不治本,属于头痛医头脚痛医脚的解决方案:

但要是你直接取parent的ActiveControl,这个窗体不嵌入其他窗体的时候不是又错了?换句话说,这个窗体跟它的使用环境发生了耦合。有没有比较好的办法来解决这个问题?

我说了三个方法,前两个都不算是通用的办法,就不说了。第三个就是我在《杂而不精》一文里我提到过的MVC模式。在这一点上,我和令狐达成一致。针对猎手这个问题使用MVC,可以把这部分功能从View剥离到Control上去处理。

关于MVC,令狐有一段说明:

MVC的概念我的Blog里有提到。简单的说,就是把界面、界面需要完成的功能、这些功能所要操作到的数据对象全部分离。这样一来,比如你界面上有一个按钮和一个菜单完成同样的功能,就只要调用功能类中同样的方法即可,跟这个按钮、菜单所在的界面就无关了。

VCL中有一个Action的概念,但光有这个,支持MVC开发是远远不够的。这也是我在《杂而不精》中说过,我一直在思考的问题,早就想写一个文章来说的,不过感觉想法还不够成熟。今天既然拿来讨论了,就先简单空谈一下。

RAD让人养成很多坏习惯。比如,即使有Action这样的,做出MVC也会不伦不类,V和C的耦合度会很高的,这很不好。我设想的是RAD只做V的部分,将C部分完全剥离,这样GUI应用就会成为可测试的,用单元测试覆盖C和M。

令狐指出其中可能存在的一个问题:

VCL的问题我以前也想过,我觉得是因为VCL本身对MVC的支持就不够好。因为VCL中,已经将C的东西融合到控件本身去了,这样你再想剥离就很困难。我以前在CSDN上帮人写过一个MVC的演示,就碰到过这个问题。

举个例子,比如TMemo的Lines,存储了Memo中的内容,而这个Lines是跟TMemo本身的操作又是相关的。我那时候是自己用一个List去

记录数据,但是这样一来,就会造成Lines和我自己那份数据的重复,而且有不同步的潜在可能。后来我的解决方法是完全放弃Lines,每次我自己的

list更新之后,将Lines清空重新设置。不过这样对显示效果又有影响。

但我认为还是可以剥离的,这跟VCL的关系不太大。我在最近写的一个BLOG备份程序的GUI部分里就尝试用MVC的思想,感觉还可以。至于令狐上面的说的问题,也是可以解决的。

Memo

的Lines属性是一个TStrings *。在Control里维护一个TString *

成员指向Memo的Lines即可,由Control直接去维护Memo的Lines,这样就不存在一式两份的问题。因为Memo的Lines属性是不可

更改的,所以只能通过Control去操作。不过程序中的其它代码不能直接对Memo的Lines进行操作,而是要通过Control进行。

把我的思路总结一下就是这样:

我把V和C之间的关系简化为三种:Action, State, Contraint

Action代表对界面的操作,调用Control的相应函数处理

State代表界面状态的改变,由Control去执行

Constraint代表约束,即Action和State的关联,比如在某种状态下不能出现某个Action

这个Constriant又有两种,强约束和弱约束

弱约束可以在View中实现

强约束可能在Control中实现,也可能在Model中实现

有必要补充一下:其中关于Constraint的想法,最早来自于去年与Chechy讨论他的一个基于XML的框架时受到的启发。

实际上弱约束的情况很少,它通常不能算作业务逻辑的一部分,为了简单起见才把它放在VIEW这边实现。如令狐所说,弱约束差不多就是指控件Disable或者Invisible这种。不过有些Disable/Invisible可能还是要放到Control里的。

令狐作了一下归纳:

户对界面元素进行一个操作,发出一个request,实际触发一个控件事件,这个事件将会调用Control,Control继续调用业务模块,业务模块

完成实际业务逻辑并返回,根据返回值,Control做两种可能的操作:转向另一个页面,或改变当前页面的某些状态(或两者兼具);而页面上的控件由

View类负责,View类接受到状态改变后,对控件实际的表现形式进行对应修改。

整个流程是:

View's

Event->Process Control->Business Control->Model->Model

return->Business Control return->Process Cotrol's state change OR

open new view->View class(change form's control)

基本上就是这样,这样做还有一个很大的好外就是,可以比较方便地更换VIEW层。比如从PC移到PDA,或移到WEB。

令狐补充了一点:

样的话,View层由两部分组成:Form和View class,Form负责可视化、用户事件接收,View

class负责处理状态的改变。然后,你所谓的强约束,可以几乎肯定是做在Process Control或Business

Control层;而弱约束,几乎肯定是做在View Class

如果考虑到View层的更换,是必须加入View Class的,这是我开始没有考虑到的,我原来设想中这部分功能是在control里的。所以还是有很多不够成熟的地方,需要再讨论讨论。最主要的是需要经过实践的考验才行。

令狐又提了两个重要的问题:

1、Windows的控件有的时候是界面相应先于逻辑处理,比如Checkbox,你一点它就直接改变状态了,但是后端的逻辑处理可能又会重复修改它的状态。

2、还有个更严重的问题,对某些控件状态或内容的修改,会触发一些事件,这样会造成一些事件的递归调用或Control的难以控制

在传统的Web程序中,这个问题比较不明显,因为你在View上做的操作都不会产生实际的影响,直到Submit才会去服务器进行MVC的流程,但是客户端就没这么简单了,每个操作都可能会这样跑一圈

事实上,这两个问题在传统RAD开发中都存在,特别是第二个问题尤其严重,并且都很难解决。我起初考虑在GUI应用开发中采用MVC模式,很重要的一个原因就是为了解决如上面的第二个问题。

于第一个问题是这样:当check时就会产生Action,它调用到control这边时就可以根据情况处理,如果知道这是一个需要Model做长时间处

理的,就可以先改变界面的状态,比如把光标设置成hourglass,在Model处理完成之后再更新checkbox状态,并恢复光标。当然,最终的状

态要以Model的处理结果而定,由control去更新view的state。

而第二个问题的解决之道就在于所有的Event都会转为Control的Action请求,当第一个请求到达Control时,就会启动相关的Constraint。之后的请求就会根据Constraint发生不同的作用——比如有些就会被屏蔽掉。

令狐又提出第三个技术问题:还有一个问题就是环境上下文如何传递

这个问题在GUI应用中还是比较好解决,但在WEB应用中就麻烦一些。在GUI应用中,上下文可以直接或间接(通过指针指向View中的控件属性,如前面说的那个Lines)记录在Control中。但因为Web应用是无状态的,所以需要额外的持久化机制。

令狐说:持久化机制在服务器端利用数据库、在客户端利用Cookie,都有办法可以做到。

但实现方法肯定是与GUI应用不同的,要麻烦一些。

我那个试点程序对上面说的这些没有全部实现,只尝试了一下V和C的分离,所以说我还要再考虑考虑。

我同意令狐说的:看看实现在讨论比较实际,否则是空对空的。试着用上面的理论作个实现出来,如果能提升到框架是最好不过了。就算只是个思想也是好的,不过要实现出来有些问题才好讨论。

提升到框架还是有难度的,我的目标是整理出一套切实可行的做法,以改进GUI应用开发。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有