开发者

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 enou开发者_如何学Gogh reason. Is there a common way to handle this situation or a better way to approach the problem?


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.


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.


I like the approach of using a mutable object to instantiate an immutable object; the mutable object is just for tidy passing of options. One example of this in the .NET framework is ProcessStartInfo.

class XInfo {
  public int A;
  public int B;
}

class X {
  public X (XInfo i) {
    // you can transform the data/layout from i any way you need
    ..
  }
}

new X(new XInfo() {
  A = 42
})

While I'll hold my tongue about the '40 properties', I find the above approach works pretty well. An added bonus is the XInfo and the internal structure used in X can be entirely different, as long as you can provide a sane mapping.


If i go by your words "but I am not sure how to go about setting 40 properties during initialization.", it appears that your problem is a class with too many fields/properties. Doesnt seem to be a problem of making it immutable, because you already know how to do that.

I would suggest (like others), Refactor and Extract Class.


As an alternative, you can make your class derive from freezable, I think this may be the solution you are searching for. You can Instatiate the object, set the values, then set it frozen. Once you set it frozen the class is 'read only'.


I would suggest putting the parameters into one or more structures, and having the object hold those structures. Nesting objects would be possible, but would add more overhead than nesting structures.

As an alternative, you could create an abstract base class with "readonly mustoverride" versions of all your properties. From this, derive a mutable and immutable object class. The immutable one can accept the base class in its constructor, and use all the readonly properties to build the new object. The mutable class can provide a means of writing the properties using methods, read-write properties with different names from the readonly versions, etc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜