1

I've read a lot of detailed things throughout Stack Overflow, Microsoft Developer Network, and a couple of blogs. The general consensus is "A Constructor shouldn't contain large quantities of parameters." So encountering this got me thinking-

  • Initial Problem: My application contains around fifteen variables that are constantly being used throughout the application. The solution I came up with is I'll create a single class that will inject the values to the Properties.

So this seemed to work quite well, it made my life quite easy as I could pass the object into another class through the Constructor without having to assign all these variables to each method. Except this lead to another issue-

public class ServerParameters
{
    // Variable:
    private string template;
    private string sqlUsername;
    private string sqlPassword;
    private string sqlDatabase;
    private string sqlServer;

    public ServerParameter(string _template, string _sqlDatabase, string _sqlServer, 
string _sqlUsername, string _sqlPassword)
    {
        template = _template;
        sqlUsername = _sqlUsername;
        sqlPassword = _sqlPassword;
        sqlDatabase = _sqlDatabase;
        sqlServer = _sqlServer;
    }

// Link the private strings to a group of Properties.

}

So already this Constructor has become significantly bloated- But now I need to implement even more Parameters.

  • Problem Two: So I have a bloated Constructor and by implementing other items that don't entirely fit with this particular Class. My solution to this, was to create a subclass or container to hold these different classes but be able to utilize these classes.

You now see the dilemma, which has aroused the all important question- When you can only inherit once, how can you build a container that will hold all of these subclasses?

And why shouldn't you use so many parameters in a Constructor, why is it bad exactly?

My thought on how to implement a Container but I feel like I'm doing it wrong- Because I constantly get Null Reference Exception when I try to use some of these Parameters.

public class VarContainer
{
     private ServerParameter server;
     private CustomerParameter customer;

     public VarContainer(ServerParameter _server, CustomerParameter _customer)
     {
         server = _server;
         customer = _customer;
     }
}

I'm assuming it is because the internal class itself isn't actually getting those assigned variables, but I'm completely lost on the best approach to achieve my goal-

3
  • 11
    Having so many parameters suggests that the class has too many responsibilities and should probably be broken into several different classes with more defined responsibilities. If this is not the case, there is always the Introduce Parameter Object refactoring. Commented Jun 7, 2013 at 19:03
  • 1
    It doesn't seem like you've solved your initial problem. Why do you have a ServerParameters class? Why can't the properties of ServerParameters just be properties or fields of your Server object? Commented Jun 7, 2013 at 19:06
  • Have you heard of the new object initializer syntax? { Object = "whatever", So = SoOptions.On }; Just make the required params in the constructor and then the other ones using that xyntax. Commented Jun 7, 2013 at 19:10

4 Answers 4

3

The main intent of "don't do work in your constructor" is to avoid side effects where you create an object and it does a significant amount of work that can impact global state unexpectedly or even take a long time to complete which may disrupt the caller's code flow.

In your case, you're just setting up parameter values, so this is not the intention of "don't do work", since this isn't really work. The design of your final container depends on your requirements - if you can accept a variable list of properties that are set on your class (or struct) then perhaps an initializer when you construct the object is more appropriate.

Assuming that you want all of your properties from the get go, and that you want grouping like you called out in the question, I would construct something similar to:

public class Properties 
{
    public ServerProperties Server { get; private set; }
    public CustomerProperties Customer { get; private set; }

    public Properties(ServerProperties server, CustomerProperties customer)
    {
         Server = server;
         Customer = customer;
    }
 }

I'm leaving the implementation of ServerProperties and CustomerProperties to you, but they follow the same implementation pattern.

Sign up to request clarification or add additional context in comments.

Comments

1

This is of course a matter of preferences but I always give my constructors all the parameters they need so that my objects has basic functionality. I don't think that 5 parameters is bloated and adding a container to pass parameters adds much more bloat in my opinion than adding a few more parameters. By new bloat I mean that you will probably have a new file for that, with new classes and new imports. Calling code has to write more using directives and link to correct libraries which needs to be exported correctly as well.

Adding a wrapping class for parameter masks the real problem, that your class might be too complicated, it does not solve it and generally aggravates it.

Comments

0

You can have any amount of parameters you want in a constructor. It's just that if you have too many (how many is too much? that's really subjective), it gets harder and harder to make a new instance of that class.

For example, suppose you have a class with 30 members. 27 of them can be null. If you force it to receive a value for each member in the constructor, you'll get code like this:

Foo bar = new Foo(p1, p2, p3, null, null, null, null, null, null /*...snip*/);

Which is boring to write and not very readable, where a three parameter constructor would do.

IMO, this is what you should receive in your constructors:

  • First, anything that your instance absolutely needs in order to work. Stuff that it needs to make sense. For example, database connection related classes might need connection strings.
  • After those mentioned above, you may have overloads that receive the stuff that can be most useful. But don't exagerate here.

Everything else, you let whomever is using your code set later, through the set accessor, in properties.

Comments

0

Seems to me like you could use dependency injection container like Unity or Castle Windsor.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.