1、不能从算法和数据结构的组织这个层面上考虑设计,而应该从从模块和数据流的层面上考虑设计。把数据流搞清楚,按照需求,拆分成能够完成需求的各自独立的模块,让数据从起点到终点流动,被处理,最后得到结果。
比如:数据存储模块、价格发生器、价格过滤器、交叉盘价格合成器、价格发布器、视图模块;
2、根据数据流图,拆分出来的独立模块,设计类;
3、类的分别原则是:属于流程不同模块,即使功能相似或者相近,也不能合成一个类;
4、一个类只做有限的事情,大而全的类虽然有可能是一种方案,但决不是最好的方案,它增加了耦合和复杂性,维护性也很低;
5、类的实现部分,尽量不要直接调用类成员以外的数据,比在类的函数中,直接对某个全局对象调用方法,这样类函数执行的前提是:这个全局对象必须存在,而这是一种耦合。解耦是简单的,那就是把这个全局对象作为类函数的参数传入;
6、类的方法接口,应该只接受能够完成类方法所需要的数据,如果传递一个指针,这个指针包含的内容,可能远远超过类方法所需要的;
7、关于上一点的解决办法是:构建类需要参数的POD,不要怕转换,不要怕生成临时对象,事实上我需要这样做。
===========================================================================================
改进后的版本
1、界面视图本来可以承担控制器的作用,也就是MVC简化成MV。但是这样就必须让视图来处理命令,试图必须具备双向的能力:即解析命令,并向下执行同步到模型(数据);根据模型(数据),同步视图,向上更新界面;
2、控制器和视图集中在视图里面,增加了视图的复杂性,如果增加一个命令控制器,最终变成MVC,那么视图就只需要具备向上更新UI的能力,向下执行命令更改模型(数据)的能力交给了命令控制器。这样就实现了一上一下,各司其职的架构;
3、形成视图的经常不只是一种数据流,往往多种数据流共同形成一个视图:比如下面的结构中,视图是由:配置流,价格流,日志流三种组合而成的;
4、增加命令控制器的作用的事显而易见的,它让业务控制的接口可以脱离视图而存在。反过来理解,如果用视图来同时充当用户命令接口,那么用户命令接口存在的前提是视图必须存在。而视图是多变的,或者说可以根本不存在,那么把用户命令接口放在其中极其不合适。试想一下,一个项目它可以是个对话框,可以是个多文档,也可以是个控制台,多变的界面,多变的视图,但是用户命令接口确实不便的,把用户命令耦合到视图的实现里面去,就不合适了;
5、把命令控制器抽离出来的另一个好处是:集中管理用户的命令,便于维护。试想一个如果对用户命令的处理分散在若干个.cpp文件,几十个C***Dailog的On***Button()消息相应函数里面,理解,调试,维护起来,将是一件多为痛苦的事情;
6、更多想写的一句话,就是业务逻辑,不要和界面耦合起来,界面需要做的就是:显示视图,接受用户命令两个功能,其他的都没必要在界面里面存在。举个例子,用得很多的MFC OnTimer()函数,事实上定时操作应该是业务逻辑的部分,放在界面里执行就不合适了;
7、检测界面与业务逻辑耦合程度的一个标志就是:把程序里界面代码剥离后,业务逻辑依然完整,程序依然可以运行。如上面所说的,界面中处理OnTImer()函数,则去掉界面代码后,业务逻辑就不完整了,少了执行定时业务处理的部分,这就是一中明显的界面与业务逻辑耦合。
8、程序可以分为很多功能模块,命令控制器能够控制这些功能模块的行为是应该,这些功能模块输出信息到视图里面也是应该的。
===========================================================================================
struct ViewResult
{
struct ViewSource
{
char symbol[12];
int digits;
double minprice;
double minspread;
double peerminm;
BOOL usepremium;
double premiumex;
char session_current;
char remark[256];
BOOL session_enable;
} view_source;
struct ViewTrans
{
BOOL b_bid_success;
BOOL b_ask_success;
}view_trans;
struct ViewPrice
{
double bid;
double ask;
}view_price;
};
BOOL UpdateViewSource(int index, const ViewResult::ViewSource& vs);
BOOL UpdateViewTrans(int index, const ViewResult::ViewTrans& vt);
BOOL UpdateViewPrice(int index, const ViewResult::ViewPrice& vp);
BOOL UpdateViewMsg(const ViewMsg& vm);
p