哪个设计选择复杂的对象初始化? [英] Which design to chose for complex object initialization?

查看:136
本文介绍了哪个设计选择复杂的对象初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个类封装一个(或多个)成员,它必须以某种方式被初始化,没有合理的方式使用没有它的类(所以我不想让它是可选的) 。
然后最好在其构造函数中运行初始化,如下所示:

Lets say I have a class encapsulating one (or multiple) member(s) which must in some way be initialized and there is no reasonable way to use the class without it (so I don't want to make it optional). Is it then better to have initialization run in its constructor like so:

class MyClass
{
    MyClass()
    {
        if(!obj.initialize()
            throw ...;
    }

private:
    MyObject obj;
}

或者你会建议以下设计:

or would you suggest the following design:

class MyClass
{
    MyClass()
    {
    }

    bool initialize()
    {
        return obj.initialize();
    }

private:
    MyObject obj;
}

第一个看起来很吸引人,因为我可以保证所有的使用我的类的要求在构造函数运行,我可以通过抛出异常报告任何错误。

The 1st one looks appealing because I can guarantee all requirements for using my class have been met after the constructor has run and I can report any errors by throwing an exception.

第二个看起来不错,因为它不会重载构造函数,直观地不属于那里,特别是一次初始化例程变得复杂,即创建窗口小部件,打开数据库连接,初始化第三方库等。在很多遗留代码中,我使用的是,ctors充斥着参数和初始化的东西,可能在这种类型之前运行成千上万的代码行的of肿的对象建设甚至完成。试图将这些重构为更清洁的东西在某些时候是非常困难的,因为涉及太多的依赖。这是动机我的问题。

The 2nd looks good because it doesn't overload constructors with stuff that intuitively doesn't belong there, especially once the initialization routine gets complex and i.e. creates widgets, opens database connections, initializes 3rd party libraries etc. In a lot of legacy code I'm working with, ctors are flooded with parameters and intialization stuff, probably running thousands of code lines before this type of bloated object construction is even done. Trying to refactor these into something cleaner is really hard at some point because there are too many dependencies involved. That's what motivated my question.

设计#2的最大缺点我可以看到,我需要一个公共初始化程序,客户端必须记得调用。但是由于这可能并且可能会被遗忘,我必须跟踪和检查所有公共成员的初始化状态,并以某种方式处理错误(可能是断言会做)。

The big disadvantage of design #2 I can see is that I need a public initialization routine which the client must remember to call. But since this can and probably will be forgotten, I have to track and check intialization state in all public members and somehow treat errors (probably an assert will do). This will also clutter my class with stuff that's not there if I chose design #1.

这是我最好的选择吗?

推荐答案


第一个看起来很吸引人,因为我可以保证在构造函数运行后满足使用我的类的所有要求....

"The 1st one looks appealing because I can guarantee all requirements for using my class have been met after the constructor has run ...."

这种必须是设计不好的情况。

This must be the case otherwise the design is bad.

当构造函数完成后,对象 必须可用,无任何未定义的行为和根据其接口规范。

When the constructor completes then the object must be usable without any undefined behaviour and according to its interface specification.

不能 是指

我喜欢从配置中分离出初始化

例如,查看 std :: fstream 。您可以在不打开任何文件的情况下创建完全初始化的 fstream对象

For example look at std::fstream. You can create a completely initialized fstream object without opening any files:

std::fstream fs; // initialized but not configured

它不具有未定义的行为,将根据其接口规范进行操作。

It does not exhibit undefined behaviour and will operate according to its interface specification.

因此,您可以使用其界面配置以达到特定目的 - 例如读取特定文件:

So you can use its interface to configure it to a given purpose - for example to read a specific file:

fs.open("myfile.txt", std::ios::in); // configured

默认构造函数 对象置于工作顺序中。

这就是说,没有理由不让其他构造函数创建配置的对象更容易:

That being said there is no reason not to have other constructors to make creating configured objects easier:

std::fstream fs("myfile.txt", std::ios::in); // initialized & configured

这篇关于哪个设计选择复杂的对象初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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