Java: how to deal with "almost" immutable data structures?

Immutable objects are great because they do not require special care or feeding in multi-threaded applications. However, many objects cannot be naturally immutable. For example, an order that is sent is processed and assigned a permanent identifier after filling out the order. The identifier cannot be specified at the time of creating and sending the order, but will arrive later (or perhaps never).

Possible solutions:

  • Assign an additional unique identifier during order creation. Then, when the permanent (order is filled) ID arrives, saves it on the card. So the order class would be unchanged. Then, if the card key does not exist, we would know that the order was not filled yet. (If the Map is a static class field?)
  • Another solution is to make the constant identifier field change the corresponding synchronization. In addition, we could limit the ID to be set only once in the facility lifetime.

Are these decisions reasonable? Any other ideas? Thanks.

+4
source share
5 answers

Make the class immutable and make null valid value for the identifier. When you have an identifier for assignment, replace the existing immutable object with a new one that is identical, except that it has a new identifier instead of the old one. I like to use methods called withX for this purose.

 Foo foo = new Foo("bar"); ... foo = foo.withId(12345); // replace foo with new derived object 
+9
source

They sound like two different objects to me , order and filled order . One of them is a copy of the other with an identifier ...

What do you think of the immutability you are interested in? How will this affect your domain model? For example, I saw that the "domain" objects have an id field to just go to sleep, but they will not have id values ​​until hibernation gives them them. In this case, the domain object is weak.

Object model from a business perspective (in my academic example) assumes no identifier needed. However, an identifier is required for the model from a technical point of view (more specifically, hibernate wants one). There is clearly tension there, so I like clearly what I'm trying to model (business or technical).

Of interest, what does the identifier mean in your example?

So, when we think about the idea of identity (in the sense of Eric Evans), for an object or Entity to exist, it must have an identity ( Entities are equal if their identities are equal regardless of whether their contents are equal). For me it means

There is no point in a new version of Entity without identity (in this case, a id )

I also suggest

There is no such thing as an “almost” immutable object; it is either immutable or not

If you use the work described above, you must be sure that your object is no longer immutable. This may be good (again, why do you want immutability?). I don't think that having a domain object that can have a null for id (which is later replaced in the copy) is a good idea. This makes a “special case” that can be avoided by modeling it differently and opening up the possibility for you to handle a special case in many places (potentially).

+3
source

I think the second approach is best, using synchronization as needed. The overhead of lazy initialization and synchronization of the getter object is probably negligible.

I also suspect that the first approach will have equivalent (or worse) overhead if you compare the full implementations. For example, he will need to either synchronize the card, or use a parallel card with its own overhead. And the fact that the card is a common data structure means that the probability of a dispute will be higher than for a getter on an object (in general) that is not divided.

+2
source

Define the identifier owner class that contains the field for the identifier. When an order is created, create a new owner-ID object with an empty identifier and assign it in order. The order itself will technically be shallow, but no attempts are made to “reuse” the identifier objects for different orders, the only changes that can take place for the owner ID object will be those that should be applied to the order or any copies of it.

+1
source

Make the class immutable by following these guidelines:

a) ensure that the class cannot be overridden - make the class final or use static factories and keep private constructors

b) make the fields private and final

c) force the calling objects to complete the creation of the object in one step, instead of using the constructor with no arguments in combination with subsequent calls to setXXX methods (i.e., avoid Java Beans convention)

d) do not provide any methods that can in any way change the state of an object, not just setXXX methods, but any method that can change state

e) if the class has any mutable fields of the object, then they must be protected when passing between the class and its caller

Link for link: http://www.javapractices.com/topic/TopicAction.do?Id=29

-1
source

Source: https://habr.com/ru/post/1340505/


All Articles