What are the best practices for determining the tasks of Constructor, Initialization and Reset methods

前端 未结 5 1682
长发绾君心
长发绾君心 2021-01-22 08:38

This is a general OOP question although I am designing in Java. I\'m not trying to solve a particular problem, just to think through some design principles.
From my experien

相关标签:
5条回答
  • 2021-01-22 08:52

    I would design my classes in a way so that an "init" method is not required. I think that all methods of a class, and especially public methods, should guarantee that the object is always left in a "valid" state after they complete successfully and no call to other methods is required.

    The same holds for constructors. When an object is created, it should be considered initialized and ready to be used (this is what constructors are for and there are numerous tricks to achieve this). Otherwise, the only way that you can safely use it is checking if the object has been initialized in the beginning of every other public method.

    0 讨论(0)
  • 2021-01-22 08:54

    Is there a reason init() and reset() need to be different? It's hard to see in this simple example why the "does not instantiate anything" rule is important.

    Beyond that, I think objects should be useful as soon as they're constructed. If there's a reason -- some circular dependency or inheritance issue -- an object has to be "initialized" after construction, I would hide the constructor and the initialization behind a static factory method. (And probably move the initialization code to a separate configurator object for good measure.)

    Otherwise you're counting on callers always to call both the constructor and init(), and that's a non-standard pattern. We have some old, too-useful-to-throw-away code here that does that; it's an abstract dialog class, and what happens is, every time someone extends it, they forget to call constructUI() and then they waste 15 minutes wondering why their new dialog is empty.

    0 讨论(0)
  • 2021-01-22 09:00

    I come from a C++ background where the rules are a bit different from Java, but I think these two-stage initialization principles apply in the general case.

    Construction

    1. Everything that can be done at construction time should be done at construction time.
    2. Minimize the amount of "badness" that can result from trying to use your object before calling init().
    3. All member variables need a value, even if it's a normally invalid sentry value (e.g., set pointers to null). I think Java will initialize all variables to zero by default, so you need to pick something else if that's a valid number.

    Initialization

    1. Initialize those member variables that depend on the existence of other objects. Basically, do the things you couldn't do at construction time.
    2. Ensure your object is now in a complete, ready-to-use state. Consider throwing an exception if it isn't.

    Reset

    1. Think long and hard about what state The System will be in when you'd want to call such a function. It may be better to create a new object from scratch, even if that operation seems expensive. Profile your code to find out if that's a problem.
    2. Assuming you got past item 1, consider writing a method to handle the things that both reset() and your constructor need to do. This eases maintenance and avoids code duplication.
    3. Return your object to the same state it was in after init().
    0 讨论(0)
  • 2021-01-22 09:00

    Interesting. I especially find this construction useful if you have an object that needs to perform IO operations. I do not want anything to perform IO operations direct or indirectly in their constructor. It makes the object a nightmare to use.

    0 讨论(0)
  • 2021-01-22 09:10

    Can't say that I've ever used this exact pattern, but I've used similar things to reduce code duplication. For example when you have an object that may be either created via a constructor or from a another object (like a DTO) via a factory method. In that case, I'll often have an internal initializer that populates the properties of the object that is used by both. Can't say that I've ever used a "reset" method, nor do I see a real need for one if all it does is replicate the process of creating a new object.

    Lately, I've moved to only using default constructors and using property settors to initialize the object. The new C# syntax that allows to easily do this in a "constructor-like" format makes this every easy to use and I find the need to support parameterized constructors disappearing.

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