我的班的建设者应该做多少工作? [英] How much work should constructor of my class perform?

查看:144
本文介绍了我的班的建设者应该做多少工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个代表数据流的类,它基本上是
读取或写入文件,但首先数据被加密/解密,并且还有一个底层的编解码器对象来处理被访问的媒体。

I have a class that represents a data stream, it basically reads or writes into a file, but first the data are being encrypted/decrypted and there is also an underlying codec object that handles the media being accessed.

我试图以RAII的方式写这个类,我想要一个干净,漂亮,可用的设计。

I'm trying to write this class in a RAII way and I'd like a clean, nice, usable design.

我困扰我的是,现在有很多工作在构造函数中完成。
在对象的I / O例程可以安全使用之前,首先编解码器需要初始化(这不是很苛刻),但是然后考虑一个密钥,并且加密和其他事情被初始化 - 这些需要对媒体进行一些分析,这需要相当多的计算。

What bothers me is that right now there is a lot of work being done in the constructor. Before the object's I/O routines can be safely used, first of all the codec needs to initialized (this isn't very demanding), but then a key is taken into account and crypto and other things are intialized - these require some analysis of the media which takes quite a lot of computation.

现在我在构造函数中做所有这一切,这需要很长时间。我想把移动加密的init东西(大部分工作)从ctor到一个单独的方法(比如说, Stream :: auth(key)), ,这将向类的用户移动一些责任,因为他们需要在之前运行 auth()他们调用任何I / O操作。这也意味着我必须在I / O调用中检查以确认 auth()已被调用。

Right now I'm doing all this in the constructor, which makes it take a long time. I'm thinking of moving the crypto init stuff (most work) out of the ctor into a separate method (say, Stream::auth(key)), but then again, this would move some responsibility to the user of the class, as they'd be required to run auth() before they call any I/O ops. This also means I'd have to place a check in the I/O calls to verify that auth() had been called.

你认为一个好的设计是什么?

What do you think is a good design?

PS我读过类似的问题,但我真的不能应用这个案例的答案。他们大多是It depens...: - /

P.S. I did read similar question but I wasn't really able to apply the answers on this case. They're mostly like "It depens"... :-/

谢谢

推荐答案

唯一真正的金不可破坏的规则是在构造函数执行后,类必须处于一个有效,一致的状态。

The only truly golden unbreakable rule is that the class must be in a valid, consistent, state after the constructor has executed.

您可以选择设计类,使其在构造函​​数运行后处于某种空/非活动状态,或者您可以将其直接设置为活动状态in。

You can choose to design the class so that it is in some kind of "empty"/"inactive" state after the constructor has run, or you can put it directly into the "active" state that it is intended to be in.

通常,应该优先使用构造函数构造您的类。通常,你不会考虑一个类完全构造,直到它实际上准备使用,但异常确实存在。
不过,请记住,在RAII中,其中一个关键的想法是,类不应该存在
,除非它准备好了,初始化和可用。这就是为什么它的析构函数做清理,这就是为什么它的构造函数应该做设置。

Generally, it should be preferred to have the constructor construct your class. Usually, you wouldn't consider a class fully "constructed", until it's actually ready to be used, but exceptions do exist. However, keep in mind that in RAII, one of the key ideas is that the class shouldn't exist unless it is ready, initalized and usable. That's why its destructor does the cleanup, and that's why its constructor should do the setup.

同样,异常确实存在(例如,一些RAII对象允许您释放资源,并提前执行清理,然后让析构函数不做任何事情。)
所以在一天结束,这取决于,你必须使用自己的判断。

Again, exceptions do exist (for example, some RAII objects allow you to release the resource and perform cleanup early, and then have the destructor do nothing.) So at the end of the day, it depends, and you'll have to use your own judgment.

从不变量的角度考虑它。如果我给你的班级的一个实例,我可以依靠什么?我可以放心地假设,它越容易使用。如果可能准备使用,并且可能处于某些已构建但未初始化状态,并且

Think of it in terms of invariants. What can I rely on if I'm given an instance of your class? The more I can safely assume about it, the easier it is to use. If it might be ready to use, and might be in some "constructed, but not initialized" state, and might be in a "cleaned up but not destroyed" state, then using it quickly becomes painful.

另一方面,如果它保证如果对象存在,那么它可以被用作 - 是,那么我知道我可以使用它,而不必担心之前做了什么。

On the other hand, if it guarantees that "if the object exists, it can be used as-is", then I'll know that I can use it without worrying about what was done to it before.

这听起来像你的问题是,你在做

It sounds like your problem is that you're doing too much in the constructor.

如果将工作拆分成多个较小的类怎么办?有编解码器被单独初始化,然后我可以简单地将已经初始化的编解码器传递给你的构造函数。并且所有的验证和加密的东西和什么也可能被移出到单独的对象,然后简单地传递到这个构造函数一旦他们准备好了。

What if you split the work up into multiple smaller classes? Have the codec be initialized separately, then I can simply pass the already-initialized codec to your constructor. And all the authentication and cryptography stuff and whatnot could possibly be moved out into separate objects as well, and then simply passed to "this" constructor once they're ready.

然后剩下的构造函数不必从头开始做,而是可以从一些已经初始化并准备好使用的辅助对象开始,所以它只需要连接点。

Then the remaining constructor doesn't have to do everything from scratch, but can start from a handful of helper objects which are already initialized and ready to be used, so it just has to connect the dots.

这篇关于我的班的建设者应该做多少工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆