How many constructor arguments is too many?

前端 未结 15 1187
[愿得一人]
[愿得一人] 2020-11-29 15:03

Let\'s say you have a class called Customer, which contains the following fields:

  • UserName
  • Email
  • First Name
  • Last Name

相关标签:
15条回答
  • 2020-11-29 15:52

    I'd encapsulate similar fields into an object of its own with its own construction/validation logic.

    Say for example, if you've got

    • BusinessPhone
    • BusinessAddress
    • HomePhone
    • HomeAddress

    I'd make a class that stores phone and address together with a tag specifying wether its a "home" or a "business" phone/address. And then reduce the 4 fields to merely an array.

    ContactInfo cinfos = new ContactInfo[] {
        new ContactInfo("home", "+123456789", "123 ABC Avenue"),
        new ContactInfo("biz", "+987654321", "789 ZYX Avenue")
    };
    
    Customer c = new Customer("john", "doe", cinfos);
    

    That should make it look less like spaghetti.

    Surely if you have a lot of fields, there must be some pattern you can extract out that would make a nice unit of function of its own. And make for more readable code too.

    And the following is also possible solutions:

    • Spread out the validation logic instead of storing it in a single class. Validate when user input them and then validate again at the database layer etc...
    • Make a CustomerFactory class that would help me construct Customers
    • @marcio's solution is also interesting...
    0 讨论(0)
  • 2020-11-29 15:56

    I think the "pure OOP" answer is that if operations on the class are invalid when certain members aren't initialized, then these members must be set by the constructor. There's always the case where default values can be used, but I'll assume we're not considering that case. This is a good approach when the API is fixed, because changing the single allowable constructor after the API goes public will be a nightmare for you and all users of your code.

    In C#, what I understand about the design guidelines is that this isn't necessarily the only way to handle the situation. Particularly with WPF objects, you'll find that .NET classes tend to favor parameterless constructors and will throw exceptions if the data has not been initialized to a desirable state before calling the method. This is probably mainly specific to component-based design though; I can't come up with a concrete example of a .NET class that behaves in this manner. In your case, it'd definitely cause an increased burden on testing to ensure that the class is never saved to the data store unless the properties have been validated. Honestly because of this I'd prefer the "constructor sets the required properties" approach if your API is either set in stone or not public.

    The one thing I am certain of is that there are probably countless methodologies that can solve this problem, and each of them introduces its own set of problems. The best thing to do is learn as many patterns as possible and pick the best one for the job. (Isn't that such a cop-out of an answer?)

    0 讨论(0)
  • 2020-11-29 16:00

    Unless it's more than 1 argument, I always use arrays or objects as constructor parameters and rely on error checking to make sure the required parameters are there.

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