How many constructors should a class have?

前端 未结 16 1855
一向
一向 2021-02-04 12:34

I\'m currently modifying a class that has 9 different constructors. Now overall I believe this class is very poorly designed... so I\'m wondering if it is poor design for a clas

相关标签:
16条回答
  • 2021-02-04 12:59

    It seems to me that this class is used to do way, way to much. I think you really should refactor the class and split it into several more specialized classes. Then you can get rid of all these constructors and have a cleaner, more flexible, more maintainable and more readable code.

    This was not at direct answer to your question, but i do believe that if it is necessary for a class to have more than 3-4 constructors its a sign that it probably should be refactored into several classes.

    Regards.

    0 讨论(0)
  • 2021-02-04 13:00

    I limit my class to only have one real constructor. I define the real constructor as the one that has a body. I then have other constructors that just delegate to the real one depending on their parameters. Basically, I'm chaining my constructors.

    Looking at your class, there are four constructors that has a body:

    public MyManager(ISomeManager someManager) //this one I added
    {
        this.someManager = someManager;
    }
    
    public MyManager(SomeClass someClass, DateTime someDate)
    {
        if (someClass != null)
           myHelper = new MyHelper(someOtherClass, someDate, "some param");
    }
    
    public MyManager(SomeOtherClass someOtherClass, DateTime someDate)
    {
        myHelper = new MyHelper(someOtherClass, someDate, "some param");
    }
    
    public MyManager(YetAnotherClass yetAnotherClass, DateTime someDate)
    {
        myHelper = new MyHelper(yetAnotherClass, someDate, "some param");
    }
    

    The first one is the one that you've added. The second one is similar to the last two but there is a conditional. The last two constructors are very similar, except for the type of parameter.

    I would try to find a way to create just one real constructor, making either the 3rd constructor delegate to the 4th or the other way around. I'm not really sure if the first constructor can even fit in as it is doing something quite different than the old constructors.

    If you are interested in this approach, try to find a copy of the Refactoring to Patterns book and then go to the Chain Constructors page.

    0 讨论(0)
  • 2021-02-04 13:02

    If you arbitrarily limit the number of constructors in a class, you could end up with a constructor that has a massive number of arguments. I would take a class with 100 constructors over a constructor with 100 arguments everyday. When you have a lot of constructors, you can choose to ignore most of them, but you can't ignore method arguments.

    Think of the set of constructors in a class as a mathematical function mapping M sets (where each set is a single constructor's argument list) to N instances of the given class. Now say, class Bar can take a Foo in one of its constructors, and class Foo takes a Baz as a constructor argument as we show here:

        Foo --> Bar
        Baz --> Foo
    

    We have the option of adding another constructor to Bar such that:

        Foo --> Bar
        Baz --> Bar
        Baz --> Foo
    

    This can be convenient for users of the Bar class, but since we already have a path from Baz to Bar (through Foo), we don't need that additional constructor. Hence, this is where the judgement call resides.

    But if we suddenly add a new class called Qux and we find ourselves in need to create an instance of Bar from it: we have to add a constructor somewhere. So it could either be:

        Foo --> Bar
        Baz --> Bar
        Qux --> Bar
        Baz --> Foo
    

    OR:

        Foo --> Bar
        Baz --> Bar
        Baz --> Foo
        Qux --> Foo
    

    The later would have a more even distribution of constructors between the classes but whether it is a better solution depends largely on the way in which they are going to be used.

    0 讨论(0)
  • 2021-02-04 13:02

    The awnser is: NONE

    Look at the Language Dylan. Its has a other System.

    Instat of a constructors you add more values to your slots (members) then in other language. You can add a "init-keyword". Then if you make a instance you can set the slot to the value you want.

    Ofcourse you can set 'required-init-keyword:' and there are more options you can use.

    It works and it is easy. I dont miss the old system. Writing constructors (and destructors).

    (btw. its still a very fast language)


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