Practice First

实践第一

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

构造函数中为什么不适合放一些比较昂贵的操作

例如我有一个数据库类
public class DataBase
{
         public DataBase( string
serverName )
         {
             
………//
连接数据库
         }
}

这样设计有什么不好的?

————————————————
from Zip
<Framework Design Guided Line>
中有一条建议就是 lazy constructor

———————————————–
from Shenghe
呵呵
就是说只有在需要的时候才去执行相应的操作,是把?
恩,是个理由

但是对这个例子来说,创建一个这样对象,

然后没有联接数据库是没有什么意义的
那这种情况的话,我直接在构造函数中执行这样的操作有什么问题呢?
———————————————–
from Zip
也没有什么不好,事事无绝对,

只是遵循一定的规则可以更多的避免将来可能的错误,这些规则都是经验总结,今天不明白他的精妙没关系,或许有一天就 能明白了,先按他说的做,至少不会比自己的方法更糟糕。

———————————————
from Dave
不懂c#.
在c++里面,构造函数没有返回值,

所以尽量不把操作放到ctor里,除非使用
exception

——————————————-
———————————-
from Shaking
构造函数产生 exception  会带来很多不便。

———————————-
from Shenghe
例如我们来设计FileStream
构造函数传入一个文件路径,我感觉这个时候如果检验路径是否存在,如果不存在就抛出异常很合理阿

当然也可以在open的时候抛异常

———————————–
from Shaking
我遇到过几个例子,构造函数中做了太多事情,导致了麻烦。但我不知道是否有一般性的原则,指导构造函数所应该做的内容。

———————————–
from YangZhiqiang
理论上来讲,构造函数只是让你构造一个对象,
从这个职责上来讲的话,只要构造了这个对象就可以了。而使用这个对象的人也假定你在里面只做了简单的初始,没做什么复杂的东西。主要的其他 的动作放到其他函数里执行最好。

要 理解这个比较困难,从面向对象的角度来讲的话,类提供了很多的函数,这些函数值应该做这些函数规定的事情,而且值应该做这个函数规定作的事情,这样才能在
协议的基础上而不是在实现的基础上设计系统。构造函数也是这样的,从协议层次上来讲,构造函数就是做初始化相关东西的,不应该做其他的东西。你如果要打开 数据库,最好加一个明确的方法,这个方法用来打开数据库。这样从协议的层次上来讲变得完全了,你从构造函数里搞得话,缺少了数据库打开的操作,这样的类看
起来不是很好。

还有,在设计类的方法时,操作尽量的更小颗粒,就是把一些操作尽量分解成多点方法,这样给用户提供了更好的可控性。当然也曾加了使用的麻烦性,这样 可以通过一个更大的方法来实现。看起来复杂了,但是做出来的类比较好用。也比较健壮。

不 管是C++还是Java还是C#,只要是面向对象的语言都是差不多的,系统要建立在协议的基础上,这样造出来的系统比较健壮。每个类,每 个模块,每个运行 的程序,每个计算机什么的都建立在协议的基础上运行,这样整个系统具有很强的Flexible和 健壮性。就像网络建立在TCP等协议上一样,即使不同的操 作系统都可以搞到一起。文本文件建立在文本协议的基础上,搞到哪里都可以打开,不管内容是什么样的。

系统耦合性好不好要看组成的系统间的协议好不好,性能好不好,看组成系统的组件的性能好不好。协议好的话,系统通过不停的替换组成系统的组件可以达 到好的性能。如果协议不好的话,整个系统进化起来就比较困难。也就很快就发展到了协议的极限。

上面说的就是面向对象设计时,协议的重要性。大家都遵守的系统的协议,整个系统才能很好的达到要求。构造函数也是一个协议,所以最好遵守这个协议。

题外话:可能语言的设计者就设定下了一个构造函数只能作简单的操作,所以对构造函数支持的比较少,或者做了其他的一些处理,这样导致构造函数出问题 时,不如普通函数好处理。这也是一个协议。虽然只是潜规则。

————————————
from Shaking
这方面会产生一些模糊和混淆。
比如,某对象,用来封装数据库,则连接数据库看起来就是天经地义的 "构造" 任务。
不过,我仍然认为,应该把构造函数做成永远不会构造失败的。

另外,我对 exception 颇有戒心。在使用中,会有很多陷阱。要真正正确使用异常并 不容易,而且由于一场先天的特性,有些陷阱难以避免。

————————————-
from YangZhiqiang
其 实程序怎么做都是无所谓,呵呵,这个没有可不可以的问题。关键是如何做好,这里面有很多的学问,完成一个功能有很多方法。完成功能只是其中的一个,考量一
个系统好坏有很多指标,系统地可进化性,稳定性,性能,当然还有钱了。呵呵。钱少的时候,在构造函数里做初始化也无所谓了,玩笑了。在这里面做初始化不是 不行,是不推荐。可能会导致问题,具体有什么问题,你可能碰得到也可能碰不到,系统小的时候什么问题都没有,大了可能出问题。你在构造函数里初始化一个巨
大的数据库,搞不好会出人命。初始个小的数据,也不会有问题,而且这样做起来作程序的效率相对来说要高一些。呵呵,造大厦由大厦的造法,造民宅有民宅的造 法,关键还是要合理。

————————————–
from Shenghe
Do minimal work in the constructor. Constructors should not do much work other
than to capture the constructor parameters. The cost of any other processing
should be delayed until required.
Do throw exceptions from instance constructors if appropriate.
MSDN上的原文

————————————-
from Shaking
有没有提出理由呢?
虽然我非常支持 ctors 应该做最少的事情。但我没有很强的理由。所以很想知道 专家是什么意见。

我认为

   1. ctor 应该做最少的事情
   2. ctor
做的事情,不应该失败。少做事情,只做最简单的事情,以便保证成功。
posted on 2010-10-07 10:13  caoshenghe  阅读(750)  评论(0编辑  收藏  举报