Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to instantiate a large immutable type?

I have a type with about 40 properties (all value types) that represents a type of transaction for my business. An instance of this class corresponds to a row in my database. I would like to keep my class immutable since it will only ever be used for read operations, but I am not sure how to go about setting 40 properties during initialization.

Typically I use constructor initialization for immutable types, but I would like to avoid writing a constructor with 40 parameters. The setters for my properties are currently private though I am willing to change with good enough reason. Is there a common way to handle this situation or a better way to approach the problem?

like image 347
Nick Larsen Avatar asked Nov 29 '22 19:11

Nick Larsen


2 Answers

Quick point. You mentioned your setters on the object are private. If that is the case then your object is not immutable (otherwise setters couldn't exist). At best your object is read only.

For a true immutable object there is no choice but to have the constructor take in all of the values necessary to initialize the object. The best way to reduce the number of parameters in the constructor is to group the values into bigger objects which are then passed to the constructor. Although I wouldn't do that unless the values are otherwise logically related.

If your immutable type does truly need the 40 values and they are otherwise unrelated, the best approach is to have a constructor with 40 values. That or further break down the big immutable object.

like image 45
JaredPar Avatar answered Dec 05 '22 07:12

JaredPar


Your problem isn't so much a constructor with 40 arguments, but a class with 40 fields.

I'd recommend breaking this down. Are any of the fields related in some way? If so, group them into a common object (e.g. EmailInfo), then have your big object just reference the grouping objects.

// Instead of this:
foo.EmailHeader
foo.EmailSubject
foo.Email...

// Do this:
foo.Email.Header
foo.Email.Subject

Once your class has fewer direct properties, creating a constructor that takes those grouping objects isn't so terrible.

like image 115
Judah Gabriel Himango Avatar answered Dec 05 '22 08:12

Judah Gabriel Himango