存在的必是合理的,都值得我们学习。学什么不重要,重要的是有一技之长。如果你认为MFC垃圾请不要继续看。如果你认为文档视图结构丑陋请不要继续看。如果你认为ATL过时了请不要继续看。MFC应用与框架的联系要想分离应用与框架,首先得明白它们之间的联系。用向导生产一个多文档程序观察,可以发现只有一处关联:
选择一个插件框架后:
有必要这样做嘛??这里演示了一个应用根据选择不同的插件进入不同语言的界面,当然不是为了解决多国语言版本问题而这样做(多国语言版本可以通过资源文件来解决)。这样做到底有没有必要呢??再来看下向导生产的程序界面:
这里可以清楚看到子框架、文档、视图是一个模块体,主框架、菜单、工具栏、状态条是一个模块体、后面看不见的应用app又是一个模块体。这使我想起小时候的积木,一堆不同形状的木块,可以自由的想象去搭建房子汽车。软件应该是软的,是像积木一样可以自由搭架自由组合的。有些人一直抱怨MFC死板,我也曾经热衷去的研究一些小巧的界面库WTL、fox、fltk,但是回头来看用的最多的、对自己最有帮助然而也最另自己头痛的还是MFC。软件需要美观,于是乎出来了许多基于MFC的界面库,其中BCG、XTREME算是有名气的。试想一个项目的开发需要多少人,又有多少人对BCG之类的库熟悉(即使它很好用)。我曾经遇到过一个问题:BCG的DockBar标题在上面,占用很大一部分视图,给人一种拥挤的感觉,而XTREME的标题在左侧,这样视图看上去大许多。但是引入两套界面库是不实际的,于是自己想用MFC做一个。结果是用MFC的DockBar居然加不上去,由于涉及到一些其他问题,所以无奈只能忍受那个霸道的DockBar。最让人无法忍受的是一些别出心裁的人在MFC对话框上加上一个漂亮的XP按钮,哭笑不得。我也冲动认为给我Wnd和DC就可以作出任何想要的界面效果,花上几天时间去绘制一个控件,响应各种消息,做完后才发现离专业美观相差甚远,而且放入到应用中不协调,影响软件的商品化形象。软件开发已经进入工业化时代了,手工蛮干显得笨拙,对MFC进行封装的界面库自从有了皮肤之后也显得苍白无力。到底如何才能简化软件开发,提高软件应变能力??回到软件设计的铁定律:高内聚低耦合。从面向对象到面向构件到现在流行的面向服务软件设计理念,无不遵守这条原则,不同只是技术上的更新。对于大型软件的界面开发,抛开美观(可以通过皮肤满足)不谈,MFC是值得我们研究的。从开发者的熟悉程度和提供解决方案能力来讲,MFC都是最佳选择。有人会说MFC提供的控件少,不利于开发,请清楚软件开发已经进入工业化时代了,这已经不再是问题(后续文章会陆续解决)。软件要想软下来,尽量适应变化,只有降低耦合度。我们必须把MFC向导生产的框架拿来进行解剖,斩断耦合的牵绊。这里把软件抽象看作App、MainFrame、DocView组成,从上面的剥离可以看到,App与MainFrame、MainFrame与DocView之间是松耦合的,每一个部分是内聚的。只要保证每个部分之间可以正常通信,这样一个App就可以对应多个MainFrame,一个MainFrame可以对应多个DocView。企业只要有App、MainFrame、DocView三个向导完成三者之间的通信,就足以开发各种不同需求的软件。让思维漫步在App、MainFrame和DocView剥离开之后,我又运行了向导生产的程序。发现选择菜单的时候,状态栏有信息提示。以前从没有考虑过这些再普通不过的功能是如何实现的,突然之间觉得很神奇。我打开msdn,查阅MainFrame的基类CFrameWnd,里面有个SetMessageText函数,是状态栏显示信息用的。嗯,选择菜单的时候一定会调用它。于是进入CFrameWnd的实现文件WINFRM.CPP,搜索SetMessageText发现OnEnterIdle()、OnIdleUpdateCmdUI()调用了它,
原来空闲的时候一直会检测当前菜单跟踪状态。静下心来,让思维去自由漫步,当孤独的智者。代码下载。里面有说明文件。