Timeline for how complex a constructor should be
Current License: CC BY-SA 3.0
11 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jan 14, 2014 at 12:24 | comment | added | Telastyn | @jtrana - yeah, initialize is no good. The constructor initializes to some sane default or a factory or create method builds it and returns a usable instance. | |
Jan 14, 2014 at 5:51 | comment | added | J Trana | Having had to try catching exceptions bubbling up from constructors, +1 to the arguments against this. Having worked with folks that say "No work in the constructor" though, this can also create some weird patterns. I have seen code where every object has not only a constructor, but also some form of an Initialize() where, guess what? The object isn't really valid until that's called either. And then you have two things to call: the ctor and Initialize(). The problem of doing work to set up an object doesn't disappear - C# may yield different solutions than say C++. Factories are good! | |
Jan 13, 2014 at 19:57 | comment | added | Taein Kim | I agree that DB call probably is too heavy for ctor. I just want to make sure i understand your points correctly :) | |
Jan 13, 2014 at 19:56 | comment | added | Taein Kim | So the major difference between ctor and Create is that ctor returns an instance of the class when it is successful whereas Create can return anything it wants to. With introduction of exception in C++, returning null due to an error is a bad practice. I also don't understand when you would want ClassB.Create to return something other than ClassB unless it is a factory class, which it isn't in this case. Also, I don't think there is any difference on 'using' side because you still have one try/catch whether you are using ctor or Create. Example would be useful. thanks! | |
Jan 13, 2014 at 19:20 | history | edited | Telastyn | CC BY-SA 3.0 |
expanding on answer based on comments
|
Jan 13, 2014 at 19:18 | comment | added | Telastyn | @user21479 - There's two parts to this, in the constructor and using the constructor. It's awkward in the constructor because you can't do much there. You can't return a different object. You can't return null. You basically can rethrow the exception, return a broken object (bad constuctor), or (best case) replace some internal part with a sane default. Using the constructor is awkward because then your instantiations (and the instantiations of all derived types!) can throw. Then you can't use them in member initializers. You end up using exceptions for logic, beyond try/catch everywhere. | |
Jan 13, 2014 at 19:01 | comment | added | Taein Kim | can you elaborate on "exception behavior in constructors is awkward"? If you were to use Create, wouldn't you need to wrap it in try catch just like you would wrap call to constructor? I feel like Create is just different name for constructor. Maybe i am not getting your answer right? | |
Jan 13, 2014 at 18:59 | comment | added | Euphoric | Why would something force programmer to catch exceptions where it cannot be handled? Also, those "complex constructions" are usually reserved for need of data from other parts of the system. If you can have all data passed into constructor, there is no need to create specific constructor class. | |
Jan 13, 2014 at 18:58 | comment | added | Jason Sperske | To this I would add that a Database is a heavy external dependance, suppose you want to switch databases at some point in the future (or mock an object for testing), moving this kind of code to a Factory class (or something like an IService provider) seems like a cleaner approach | |
Jan 13, 2014 at 18:57 | comment | added | Jimmy Hoffa |
Complex construction scenarios are exactly why creational patterns like you mention here exist. This is a good approach to these problematic constructions. I'm given to think about how in .NET a Connection object can CreateCommand for you so that you know the command is appropriately connected.
|
|
Jan 13, 2014 at 18:55 | history | answered | Telastyn | CC BY-SA 3.0 |