编程和贩毒
中午和师兄们一起吃饭的时候,不知道咋就说到了贩毒上面,大家都兴致勃勃的讨论贩毒的可行性和种种计策……搞得我们周围的人纷纷侧目,还在想哪个贩毒团伙这反嚣张,在学校食堂就这么讨论起了犯罪方案-_-b……师兄说,弄就弄大的,反正70g以上就是死刑,弄就多弄个几吨……
我当时那个汗啊……
不过,说起来。对于贩毒的印象,我们都限于影片电视里那一个个毒枭,极其隐秘的行事作风,一般都隐藏得极深。毒枭的接触面很小,一般都是其心腹。有些甚至见心腹都要戴个面具或者通过其他方式……这样才能尽可能少的曝光自己,通过其得力干将去做手下的具体的工作,手下的干将又再交给下线的老大,然后是小啰啰……这一路下去,毒枭就成了一个虚无的存在,却实在的统领着整个犯罪集团。
当然,其他的黑社会组织也很相似,只不过,我们恰好说到这个罢了。
这样的结构是不是一种最高效和合理的结构呢?我不知道……不过,最近的程序似乎就是走的这个路子。面向对象带来程序的封装,系统中各个模块间尽量解耦,减少彼此的干涉。看看一些流行的外部3D开发引擎,一般的结构都是有个APP类,封装了系统的主要主要功能,再由APP和系统中其他的模块进行数据交互。这样的结果,经常是在编程时,我们只需要引用其APP函数就可以了。
在用Vtree时,我们还要处理vtApp,vtWin,vtView,如果以MFC为框架的话,这些VTree的模块和Windows模块混在一起,经常有错误发生,封装性不好,不过,处理起来也更灵活。就像一个松散的结构,如果毒枭直接可以管理那些小啰啰,那样,他处理事务可能更灵活,可以直接发令,但这样总会容易造成混乱……因为小啰啰毕竟太多,一个人的力量是有限的。
用VegaPrime的时候,觉得封装就严密多了,一个vpApp就把东西全包进去了,在Winmain里面,只需要Init, Define,Configure,Update就可以用了,程序直接与APP交互,而那些场景管理什么的都在APP系统里进行。
现在我的程序是用Vtree4来作的,另外还有CG和OpenGL的一些东西,而这些都是需要引用外部库的,而最终给用户的可用版本,是需要可以进行二次开发的,把这些库全给用户也不现实。所以,需要作必要的封装。在VC6的环境下,我建了个DSW,包含两个DSP,一个Win32 Static Library,把和外部库相连接的程序封成一个类,然后再编译成静态库,另外一个MFC程序是主程序,通过调用前一个项目编译生成的静态库,执行相应的场景渲染的功能。
为了减少程序对框架的依赖性,整个程序我又再封了一个CKernel类,对于MFC来说,需要调用的只是CKernel的Init和Update方法,就可以完成场景的初始化与更新渲染。而CKernel再通过内部的成员变量封CData,CScene这些,完成系统的调度。
对于这个系统来说,系统框架就是毒枭老大了,CKernel是他的得力干将,他的命令很简单,而至于如何去调度,则看心腹的本事了……
程序框架对于CKernel是模糊的。它也不需要了解太多,他只需要把命令解析过去,再传递到下一级就够了。
说到这里,最近写程序的实实在在的感受到了责任链模式的必要性。在作设计的时候,我觉得是纸上谈兵,那些模式有什么必要?当时的确没有想到一些数据传输的问题……把要传递的数据看简单了。
现在需要传递的数据还是蛮多的,因为MFC程序只与Kernel相关联,所以每次场景更新需要程序框架中的一些数据时,需要通过若干级的传递。
比如,在场景模块,需要获得View类窗口的句柄m_HWnd,这是在MFCView中,这个值只能通过Kernel传递过去,在Kernel中建个SetHWnd方法。
Kernel-->SceneControl-->Scene,这些都是通过成员变量引用指针来建立连接关系的,而不是通过继承,所以在这三个类中,都需要一个SetHWnd方法。如下代码所示,从最初的CKernel传递到最终场景中的Vtree的vtwin中,需要四次的“转接”,就像发展下线一样,要通过四级,这样的显得还是有点麻烦。
void CKernel::SetHWnd(HWND hwnd)
{
m_pSceneControl->SetHWnd(hwnd);
}
void CSceneControl::SetHWnd(HWND hwnd)
{
m_pScene->SetHWnd(hwnd);
}
void CScene::SetHWnd(HWND hwnd)
{
vtWin->SetHWnd(hwnd);
}
似乎通过责任链模式,建立继承关系,可以简化这样的步骤……因为这样的数据传递还会有很多……而且其后的数据可能更复杂……
然而,盲目的建立继承关系,为了功能的增多而建立继承关系也是编程的大忌。从逻辑上来说,这几个应该的确是复合关系而不应该是继承关系……
持续思考中……