Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to design an immutable object with complex initialization

I'm learning about DDD, and have come across the statement that "value-objects" should be immutable. I understand that this means that the objects state should not change after it has been created. This is kind of a new way of thinking for me, but it makes sense in many cases.

Ok, so I start creating immutable value-objects.

  • I make sure they take the entire state as parameters to the constructor,
  • I don't add property setters,
  • and make sure no methods are allowed to modify the content (only return new instances).

But now I want to create this value object that will contain 8 different numeric values. If I create a constructor having 8 numeric parameters I feel that it will not be very easy to use, or rather - it will be easy to make a mistake when passing in the numbers. This can't be good design.

So the questions is: Are there any other ways of making my immutable object better.., any magic that can be done in C# to overcome a long parameter list in the constructor? I'm very interested in hearing your ideas..

UPDATE: Before anyone mentions it, one idea has been discussed here: Immutable object pattern in C# - what do you think?

Would be interested in hearing other suggestions or comments though.

like image 978
Torbjørn Avatar asked Dec 10 '08 05:12

Torbjørn


People also ask

Can we create immutable object?

Immutable class in java means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like Integer, Boolean, Byte, Short) and String class is immutable. We can create our own immutable class as well.


2 Answers

At the moment, you'd have to use a constructor with lots of args, or a builder. In C# 4.0 (VS2010), you can use named/optional arguments to achieve something similar to C# 3.0 object-initializers - see here. The example on the blog is:

  Person p = new Person ( forename: "Fred", surname: "Flintstone" );

But you can easily see how something similar can apply for any constructor (or other complex method). Compare to the C# 3.0 object-initializer syntax (with a mutable type):

 Person p = new Person { Forename = "Fred", Surname = "Flintstone" };

Not much to tell them apart, really.

Jon Skeet has posted some thoughts on this subject too, here.

like image 36
Marc Gravell Avatar answered Sep 28 '22 05:09

Marc Gravell


Use a builder:

public class Entity
{
   public class Builder
   {
     private int _field1;
     private int _field2;
     private int _field3;

     public Builder WithField1(int value) { _field1 = value; return this; }
     public Builder WithField2(int value) { _field2 = value; return this; }
     public Builder WithField3(int value) { _field3 = value; return this; }

     public Entity Build() { return new Entity(_field1, _field2, _field3); }
   }

   private int _field1;
   private int _field2;
   private int _field3;

   private Entity(int field1, int field2, int field3) 
   {
     // Set the fields.
   }

   public int Field1 { get { return _field1; } }
   public int Field2 { get { return _field2; } }
   public int Field3 { get { return _field3; } }

   public static Builder Build() { return new Builder(); }
}

Then create it like:

Entity myEntity = Entity.Build()
                   .WithField1(123)
                   .WithField2(456)
                   .WithField3(789)
                  .Build()

If some of the parameters are optional you won't need to call the WithXXX method and they can have default values.

like image 93
Andrew Kennan Avatar answered Sep 28 '22 03:09

Andrew Kennan