韩小明@xiammy的专栏

没水的地方挖井,有水的地方修渠

韩小明ID:xiammy
439356次访问,排名106好友13人,关注者67
毕业后一直在广联达工作
xiammy的文章
原创 174 篇
翻译 0 篇
转载 22 篇
评论 1133 篇
韩小明的公告
作者毕业于浙江大学,非常热爱体育运动。现在尤其热爱羽毛球运动。在休息时间非常热爱技术文章写作。
最近垃圾评论泛滥,为了不污染大家的视听,暂时关闭评论,请大家理解。
欢迎转载,但请注意,除非特别声明,本站采用Creative Commons License许可:署名,非商业。

最近评论
yb00k:感觉 这个还是个垃圾东西 适合IE7的变到IE8 就变样了 点都不规范 一点兼容性都不强....强烈支持 firefox
wuhuiran:我嵌入式数据库一直用BerkeleyDB,看到你的博文才知道还有一个SQLite,谢谢。BerkeleyDB不支持SQL
wuhuiran:我嵌入式数据库一直用BerkeleyDB,看到你的博文才知道还有一个SQLite,谢谢。BerkeleyDB不支持SQL
liquankun:瑞星还是不咋地!
白花了几个月的钱
外国的杀软不一定比国产的好!
但是国产的就是比不上国外的!
没办法!技术赶不上人家 还竟搞内讧
不经历大灾难 就不知道什么是团结!



正真的高手是不用杀毒软件的,没什么好不好的,是你自己技术不行而已
wangdei:http://www.bt285.cn BT下载 有300W部BT种子.
http://www.yaonba.com.cn NBA中文网 有200W条NBA直播
http://www.5a520.cn 小说520网 有300W部小说
http://www.bt285.cn/yazhou/ 亚洲BT 有BT亚洲
http://www.bjxlz.cn p……
文章分类
收藏
    相册
    图书
    链接
    宗刚的专栏(RSS)
    快乐学习(RSS)
    陈亮亮的专栏(RSS)
    朋友
    张恂论 OO
    言之有李(RSS)
    赵伟的小家
    存档
    订阅我的博客
    XML聚合  FeedSky

    原创 苛评VCL: 混乱的TStream收藏

    新一篇: 苛评VCL: 臃肿的Windows控件 | 旧一篇: 苛评VCL: 失望的TMenu

    为什么这么苛刻地来评论VCL的基础类设计,我已经在前一篇关于TObject的文章中讲过。今天我拿出在一次跟踪VCL代码的过程中发现的问题。在此之前,我没有任何理由会相信会存在这样的情况。

    TForm读取dfm文件创建窗体过程大家一定都比较清楚,其中负责读取的是Classes.pas单元中的TReader类,而它在实现的时候,会调用到如下的函数:

    function InternalReadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
    var
    HRsrc: THandle;
    begin { avoid possible EResNotFound exception }
    if HInst = 0 then HInst := HInstance;
    HRsrc := FindResource(HInst, PChar(ResName), RT_RCDATA);
    Result := HRsrc <> 0;
    if not Result then Exit;
    with TResourceStream.Create(HInst, ResName, RT_RCDATA) do
    try
    Instance := ReadComponent(Instance);
    finally
    Free;
    end;
    Result := True;
    end;

    大家请注意TResourceStream的方法ReadComponent。是的,我想说的其实就是这个方法。大家可以回过头来看看TStream的声明:

    ...
    function ReadComponent(Instance: TComponent): TComponent;
    function ReadComponentRes(Instance: TComponent): TComponent;
    procedure WriteComponent(Instance: TComponent);
    procedure WriteComponentRes(const ResName: string; Instance: TComponent);
    procedure WriteDescendent(Instance, Ancestor: TComponent);
    procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);
    procedure WriteResourceHeader(const ResName: string; out FixupInfo: Integer);
    procedure FixupResourceHeader(FixupInfo: Integer);
    procedure ReadResHeader;
    ...

    对于Stream这个抽象概念,很多人对它的理解过程都是曲折的。但不管怎么样,它基本特性还是比较清晰的。Read、Write、Position、Seek等等基本方法,构成了流的基本属性。

    然而,令我不明白的地方是,为什么Delphi会在基础类TStream中增加上述的那些有关Component的方法。这些显然和流的职责没有关系!

    在单一职责原则中,建议将两种不同的职责分成两个类实现,或继承、或组合。要说TStream的这些Component的方法,要么可以定义单独的Component资源类, 要么做出TStream的Helper类。但总比像VCL这样设计好吧。

    现在猜想VCL当时的设计情形,很可能Classes单元的类,很多是为了Delphi的组件系统的实现(或者说是IDE本身)。所以很多类在设计的时候,默认都引入了TComonent类。

    这么说是有根据的,不光是TStream类,在这个单元中的TParser类也是如此。我发现TParser类的时候是非常惊喜的,但是使用后发现,其规则是按照dfm来做的。在分析Delphi的源码的时候,会遇到注释不能识别的问题。

    一向认为单一职责最难把握,现在看VCL,呵呵,确实如此啊。

    发表于 @ 2007年02月05日 08:46:00|评论(loading...)|编辑

    新一篇: 苛评VCL: 臃肿的Windows控件 | 旧一篇: 苛评VCL: 失望的TMenu

    评论

    #wr960204 发表于2007-02-05 14:27:31  IP: 61.235.75.*
    这个我倒是非常同意楼主的。在Stream中加了那么多Component的方法我觉得是设计上的失败。
    优雅一点的设计方式是,在Component中加入关于Stream的方法。
    #QLongHappy 发表于2007-02-05 21:54:28  IP:
    呵呵,这个地方确实是恶心了点,比起Java的流机制就失败了很多,我想宝兰的流其实更多的是与界面窗体的流化关联起来,不过作为最早最成功的的FrameWork也不用太苛责了。
    #zeroyet 发表于2007-02-06 13:59:38  IP: 218.249.11.*
    搂主的想法有道理,但borland的想法也不无道理,因为这样从tStream的派生类都有component的操作功能,这样vcl可以把可视化资源保存到任何流中,也可以从任何流中读出,这样对我们这些多数以component来做应用的使用者来说更加容易把componet直接流化到我们自己特定的ttream派生类中,所以从vcl角度上这样做没有什么错。
    #fengjian_net 发表于2007-02-06 15:06:35  IP: 219.220.210.*
    完全消除类间的耦合往往会带来更为糟糕或效率的设计,有一点耦合未尝不好。
    #ok999ok 发表于2007-02-06 19:31:47  IP: 60.185.143.*
    楼主真的是要好好理解设计模式,而不是过度设计!----看来你只是一个简单的程序员!
    #dragonhux 发表于2007-02-06 22:09:40  IP: 221.235.50.*
    汗,请lz设计一种方法将TForm保存到文件中
    #lichaohui 发表于2007-02-07 20:23:54  IP:
    VCL的历史也比较悠久了,当时设计模式和原则还没有大行其道,
    不过说道这个问题,
    还是比较赞成delphi中的做法,
    使用TStream 保存一切的组件和控件的状态都非常方便,

    流的主要功能是对象的持久化,而对字节流的操作则是其原子功能,从这个角度来看,流对象的确应该这么设计,
    这样,每个组件或控件都不用增加一个保存到流和从流中读取的方法了,

    这也是设计模式中的一种情况吧,和访问者模式有点相似,
    设计模式还没有流行的时候,Delphi中已经使用了很多种设计模式了,当然,什么都不可能是完美的。
    除非,它还没有被写出来。
    #jiangkeredgirl 发表于2007-03-10 13:52:08  IP: 61.144.207.*
    楼主真的很了解被人写代码的想法后 再作评论
    起码的尊重都没有
    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © 韩小明