(disclaimer: use of Java knowledge below)
In your second solution, I presume one of the two approaches will take place for CanBePropertyChanged
:
- Loop through all the other entries of your
Set
to make sure none contain oldProperty1
, oldProperty2
... newPropertyN
.
- Construct a temporary object
temp
with oldProperty1
, oldProperty2
... newPropertyN
and using a standard method, e.g. Set.contains(temp)
, check that the method returns false
.
If there are no matches, then your SetPropertyOfItem
will apply the new property without further checks.
In your first solution, I presume it is doing something similar to the approaches for CanBePropertyChanged
, just that this is done as the first step within SetPropertyOfItem
. If the Item
cannot be modified, then you return a non-zero 'error code'.
The problem I see with (1) above is that you will be duplicating your class's equivalence checking, which may not be future-proof if your Items
gain new properties or constraints that affects how this equivalence is done. For both solutions, concurrency, should you choose to implement that, introduces the small possibility that the actual modification of your Item
object is not in sync with other concurrent read/write operations on either the Set
or Item
object.
Alternatives?
Therefore, I'll approach this by asking this question: How costly is it to re-construct a new updatedItem
with oldProperty1
, oldProperty2
... newPropertyN
? If that is a relatively cheap operation (e.g. you don't need to send these properties to a database to retrieve data that needs further parsing), why not consider making Item
an immutable class? This will be similar to using approach (2), just that you will be adding the non-temporary (permanent till the next modification) new updatedItem
into your Set
, and removing the old originalItem
from it. If it helps, you can even introduce a bit of syntactic sugar:
Item updatedItem = oldItem.createWithUpdate( property, newValue ); // creates a new object
if ( set.add( updatedItem ) ) {
set.remove(oldItem);
} else {
log.warn( "You cannot change property to this value" );
}
Your code can be simpler as a result. Also, a Set
by definition does not contain duplicate values, so the statement
But after each change every item in the set must still be unique
Is practically a given after an add()
operation (which, in Java, returns true
if the Set
did not already contain the specified element). Also, when your class is immutable, there is less cause for worry introducing concurrency, since objects themselves wouldn't be mutated out-of-sync. You will only need to code defensively against concurrent operations on your Set
object.
To answer the question directly
Ok, if Item
is in fact already immutable, or you prefer not to make the proposed changes above, and I have to take my pick from either two approaches, I will go with the first solution. However, instead of an int
-based return code, I will either return a boolean
or use exception-handling. I will favor the first solution because it opens up the possibility in the future to change the implementation of SetPropertyOfItem
, broadly speaking. @Kilian Foth's answer says it better in this regard.