How much work should be done in a constructor?

后端 未结 18 969
离开以前
离开以前 2020-11-27 17:40

Should operations that could take some time be performed in a constructor or should the object be constructed and then initialised later.

For example when constructi

相关标签:
18条回答
  • 2020-11-27 18:09

    Historically, I have coded my constructors so that the object is ready to use once the constructor method is complete. How much or how little code is involved depends on the requirements for the object.

    For example, let's say I need to display the following Company class in a details view:

    public class Company
    {
        public int Company_ID { get; set; }
        public string CompanyName { get; set; }
        public Address MailingAddress { get; set; }
        public Phones CompanyPhones { get; set; }
        public Contact ContactPerson { get; set; }
    }
    

    Since I want to display all the information I have about the company in the details view, my constructor will contain all of the code necessary to populate every property. Given that is a complex type, the Company constructor will trigger the execution of the Address, Phones and Contact constructor as well.

    Now, if I am populating a directory listing view, where I may only need the CompanyName and the main phone number, I may have a second constructor on the class that only retrieves that information and leaves the remaining information empty, or I may just create a separate object that only holds that information. It really just depends on how the information is retrieved, and from where.

    Regardless of the number of constructors on a class, my personal goal is to do whatever processing is necessary to prepare the object for whatever tasks may be imposed upon it.

    0 讨论(0)
  • 2020-11-27 18:10

    As for how much work should be done in the constructor, I'd say it should take into account how slow things are, how you are going to use the class, and generally how you feel about it personally.

    On your directory structure object: I recently implemented a samba (windows shares) browser for my HTPC, and as that was incredibly slow I opted to only actually initialize a directory when it was touched. e.g. First the tree would consist of just a list of machines, then whenever you browse into a directory the system would automatically initialize the tree from that machine and get the directory listing one level deeper, and so on.

    Ideally I think you could even take it as far as writing a worker thread that scans the directories breadth-first, and would give priority to the directory you're currently browsing, but generally that's just too much work for something simple ;)

    0 讨论(0)
  • 2020-11-27 18:12

    The time required should not be a reason not to put something into a constructor. You could put the code itself into a private function, and call that out of your constructor, just to keep the code in the constructor clear.

    However, if the stuff you want to do is not required to give the object a defined condition, and you could do that stuff later on first use, this would be a reasonable argument to put it out and do it later. But don't make it dependant on the users of your class: These things (on-demand initialization) must be completely transparent to users of your class. Otherwise, important invariants of your object might easily break.

    0 讨论(0)
  • 2020-11-27 18:12

    It really depends on the context, i.e. the problem that the class must solve. Should it for example always be able to show the current children inside itself? If the answer is yes, then the children should not be loaded in the constructor. On the other hand, if the class represents a snapshot of a directory structure then it can be loaded in the constructor.

    0 讨论(0)
  • 2020-11-27 18:14

    I vote for thin constructors, and adding an extra "uninitialized" state behavior to your object in that case.

    The reason: if you do not, you impose all your users to either have heavy constructors too, or, to allocate your class dynamically. In both cases it may be seen as a hassle.

    It may be hard to catch errors from such objects if they become static, because constructor then runs before main() and is more difficult for a debugger to trace.

    0 讨论(0)
  • 2020-11-27 18:14

    Arrays of objects will always use the default (no-arguments) constructor. There's no way around that.

    There are "special" constructors: The copy constructor and operator=().

    You can have a lot of constructors! Or wind up with a lot of constructors later on. Every now and then Bill out in la-la land wants a new constructor with floats rather than doubles to save those 4 lousy bytes. (Buy some RAM Bill!)

    You can't call the constructor like you can an ordinary method to re-invoke that initialization logic.

    You can't make the constructor logic virtual, and change it in a subclass. (Though if you are invoking an initialize() method from the constructor rather than manually, virtual methods won't work.)

    .

    All these things create a lot of grief when significant logic exists in the constructor. (Or at least duplication of code.)

    So I, as a design choice, prefer to have minimal constructors that (optionally, depending on their parameters and the situation) invoke an initialize() method.

    Depending on the circumstances, initialize() may be private. Or it may be public and support multiple invocations (e.g. re-initializing).

    .

    Ultimately, the choice here varies based on the situation. We have to be flexible, and consider the tradeoffs. There is no one-size-fits-all.

    The approach we'd use to implement a class with single solitary instance that's using threads to talk to a piece of dedicated hardware and that has to be written in 1/2 an hour is not necessarily what we'd use to implement of a class representing mathematics on variable-precision floating-point numbers written over many months.

    0 讨论(0)
提交回复
热议问题