今天看VC,觉得他的 “文档-视图” 应用程序框架很好,文档类CDocument只负责处理数据,视图类CView只负责显示数据,并且一个文档对象可以对应多个视图对象,即数据可以用不同的方式表示出来(例如一个视图对象以表格的形式,另一个视图对象以图形的方式)。且数据更改后,所有视图对象同步更新显示。这一同步更新的过程都由VC自动处理,多好。
但Delphi中好像没有对应的文档类和视图类,也没有提供某种方法保证不同Form中的显示同步(即使它们都是现实同一内存数据的)。 请精通Delphi和VC++的双枪将解答一下以上疑问,谢谢!!!
也许是因为出现得比较早,这种DOC/VIEW实现相对其它的架构,只能算一种比较平常
的东西,算不上优秀.至少我觉得还不如JAVA类似的MVC实现.DELPHI的数据模块,窗体,来自于中介者模式
DELPHI也用到了观察者模式的,就是在DataSet--datasource-DB Control
注意力更集中到数据库应用上面.
现在不谈谁先进,我觉得数据和显示分离这种思想比较好。Delphi 虽然可用数据模块解决一些问题,但对非数据库应用,比如自定义的数据结构,怎么保证数据与显示的同步呢?(比如我有一个自定义数据结构TData,而有10个Form以不同的方式如图、表、直方图等显示这个数据,如何作到每改变一点数据,即更新所有10个Form的显示呢?)
就由观察者模式来考虑.
假定TDATA位于一个数据模块单元,这个单元使用一个LIST,用它来维护
哪些FORM在'观察'它.
系统初始化的时候,每创建一个FORM,就在数据单元LIST加上这个FORM.当TDATA数据发生更新时候,通知所有的FORM更新显示.
至于通知的时候采用消息还是回调或者其它技术,看你喜欢.VC的DOC/VIEW好象是用的消息通知
在网络上还没有没有象样的产品:只有功能介绍:
http://www.cltess.com/html/sign.htm
偶这一组是《电子公章》就是说在
1)WORD文档中嵌入一个半透明的 悬浮公章,
2)用硬件watchsafe中的公钥对 公章加密,锁定这个文档
不被非法修改
硬件接口的DLL是这样的:
#ifdef __cplusplus
extern "C"{
#endif
int WQOpenUsbKey(void);
int WQCloseUsbKey(void);
int WQVerifyUserPin(LPTSTR password,short len);
int WQGetCertFromUsb(LPBYTE cert,LPDWORD certlen);
int WQSignWithUsbKey(unsigned char *from,int len, BYTE Hash_AlgID,unsigned char *to,int *outlen);
int WQDecryptWithUsbPrivateKey(unsigned char *from,int len, unsigned char *to,int *outlen);
int WQDecryptWithUsbKey(unsigned char *from,int len, unsigned char *to,int *outlen);
int VerifySignWithCertFile(unsigned char *from,int len, unsigned char *origndata,int datalen,BYTE Hash_AlgID);
int EncryptWithCertPublicKey(unsigned char *from,int len,unsigned char *to,int *outlen);
int EncryptWithCert(unsigned char *from,int len,unsigned char *to,int *outlen);
#ifdef __cplusplus
}
#endif
对于签章函数的int WQSignWithUsbKey(unsigned char *from,)
的第一个参数显然要求 WORD文档的 文件流,那要如何获得呢?
但有几点仍不明白,望指点一二:
1)我不是编数据库程序,你说的“假定TDATA位于一个数据模块单元,这个单元使用一个LIST,用它来维护哪些FORM在'观察'它.”那个“数据模块单元”是否指delphi的DM, DM是否可用与非数据库程序中?
2)如果采用消息,能否给个伪码写的例子(相当于示意图)。
3)还有什么技术? 千分感谢!!!
它继承自TCOMPONET,可以作一个容器类,专来放非可视控件.这样特别是当你程序里面
使用对象较多时,不会散乱.
把它作为容器来管理你自定义的数据结构或者文档模型是再合适不过了.
const
MY_NOTIFY_MSG=WM_USER+1000; //自定义一个消息...
//..................
//------------其中一个观察者---------------
type
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
procedure My_Notify(VAR msg:TMessage);Message MY_NOTIFY_MSG; end;
procedure TForm1.My_Notify(var msg: TMessage);
begin
Refresh;//这儿可以简单刷新界面或做更复杂的事..
end;//-------------------------------------------
简单对象也可以支持这种消息机制,可以做观察者type
TMyObj = class(TObject)
private
{ Private declarations }
public
{ Public declarations }
procedure My_Notify(VAR msg:TMessage);Message MY_NOTIFY_MSG; end;
procedure TMyObj.My_Notify(var msg: TMessage);
begin
//这儿可以去取被观察者数据做更复杂的事..
end;//--------------------------------------------------------------注,如果你的观察者都有WINDOWS句柄,就在被观察者LIST中维护句柄就可以.
可以用SENDMESSAGE或者POSTMESSAGE发更新通知.如果你观察者不一定有WINDOWS句柄,那就在LIST中维护一个TOBJECT的指针就可以.
可以用DISPACH发更新通知.
//用消息机制的好象是耦合较小,观察者可以忽略通知消息,处理上的一点麻烦应该完全值得//再说一句,在取文档时候,如果你的观察者是用于大粒度对象,可以考虑XML等技术,
//统一一下文档访问.
就象DELPHI的DATASET+DATASOURCE+DBCONTROL
你去跟踪一下它们的源码,会看到更丰富的观察者实现方式,
但解决问题思路的本质不变.
非常感谢HalfDream,使人茅塞顿开。
关于此话题,恐怕还要请教。
最后将双手捧上分数。