我有一个表示数据流的类,它基本上读取或写入文件,但首先是数据被加密/解密,还有一个底层编解码器对象来处理被访问的媒体.
我正在尝试以RAII的方式编写这个类,我想要一个干净,漂亮,可用的设计.
困扰我的是,现在构造函数中正在做很多工作.在可以安全地使用对象的I/O例程之前,首先需要初始化编解码器(这不是非常苛刻),但是然后考虑密钥并且加密和其他事情被初始化 - 这些需要一些分析需要大量计算的媒体.
现在我在构造函数中执行所有这些操作,这需要很长时间.我正在考虑将加密初始化的东西(大多数工作)从ctor转移到一个单独的方法(比方说Stream::auth(key)),但话又说回来,这将把一些责任转移给类的用户,因为他们需要auth() 在他们调用任何I/O操作之前运行.这也意味着我必须检查I/O调用以验证是否auth()已被调用.
你认为什么是好的设计?
PS我确实读过类似的问题,但我真的无法在这个案例中应用答案.他们大多喜欢"它取决于......": - /
谢谢
唯一真正的黄金牢不可破的规则是,在构造函数执行后,类必须处于有效,一致的状态.
您可以选择设计类,使其在构造函数运行后处于某种"空"/"非活动"状态,或者您可以将其直接置于其打算处于的"活动"状态.
通常,最好让构造函数构造您的类.通常,你不会认为一个完全"构造"的类,直到它实际上准备好被使用,但是存在异常.但是,请记住,在RAII中,关键思想之一是除非已准备好,初始化和可用,否则该类不应存在.这就是它的析构函数进行清理的原因,这就是它的构造函数应该进行设置的原因.
同样,存在异常(例如,一些RAII对象允许您释放资源并尽早执行清理,然后让析构函数不执行任何操作.)因此,在一天结束时,它取决于您,您将不得不使用你自己的判断.
从不变量的角度来考虑它.如果我有一个班级实例,我还能依靠什么?我越可以安全地假设它越容易使用.如果它可能已准备好使用,并且可能处于某种"构造但未初始化"的状态,并且可能处于"已清理但未被破坏"状态,那么快速使用它会变得很痛苦.
另一方面,如果它保证"如果对象存在,它可以按原样使用",那么我将知道我可以使用它而不用担心之前做了什么.
听起来你的问题是你在构造函数中做得太多了.
如果将工作分成多个较小的类,该怎么办?让编解码器单独初始化,然后我可以简单地将已经初始化的编解码器传递给构造函数.并且所有身份验证和加密的东西以及诸如此类的东西都可以移动到单独的对象中,然后在它们准备好之后简单地传递给"this"构造函数.
然后剩下的构造函数不必从头做任何事情,但可以从一些已经初始化并准备好使用的辅助对象开始,因此它只需要连接点.
| 归档时间: |
|
| 查看次数: |
723 次 |
| 最近记录: |