0

Let's think about this class, where ImmutablePart is an immutable pure data Object :

public class Clazz1  {
    private final ImmutablePart immu ;

    private String f1;

    private boolean f2;

    private int f3;

    /** some constructor building up the immu and 
    setting the fields to init values
    ...
    ...
    **/

    public ImmutablePart getImmu(){return immu;}

    public String getF1(){return f1;}

    public boolean getF2(){return f2;}

    public int getF3(){return f3;} 

    public void setF1(String f1){this.f1=f1;}

    public void setF2(boolean f2){this.f2=f2;}

    public void setF3(int f3){this.f3=f3;}         
}

Is it good practice to use composition at this stage, to make it more clear that one part is mutable, the other immutable, or is it just boilerplate? Like this (with MutablePart having getters and setters for the fields of Clazz1).

public class Clazz2  {
    private final ImmutablePart immu ;

    private final MutablePart mutable;

    /** some constructor building up the two final objects
    ...
    ...
    **/

    public ImmutablePart getImmu(){return immu;}

    public MutablePart getMutable(){return mutable;}

}

EDIT1 : okay to be more specific, the immutable part is build from a file containing some sort of metainfo, and therefore is not meant to change. The mutable part will evolve regarding runtime. Let's imagine I'm working on a p2p application. The immutable part will contain all informations regarding the set of files my client will share with peers, and some hashkey to insure the authenticity of received packets. Whereas the mutable part will contain informations regarding the state of the sharing, ie some states, number of bytes uploaded, number of bytes downloaded etc... The immutable part could easily be called "metaInfo", and the mutable part "context", if you want more meaningful names. But my question was more about the utility of such design. Thanks for your answers!

EDIT2 : the names I have chosen are just here for abstraction purpose, I would give better names in real implementation. That is to say, and I agree it might be confusing at first glance, that by saying "explicit" I mean a harsh distinction between both part into two different objects, not naming explicitly one part "Immutable" and the other part "mutable".

Jules Sam. Randolph
  • 3,610
  • 2
  • 31
  • 50

3 Answers3

1

On your level of detail this cannot be decided, but with some additional requirements such a split could be desirable.

Specifically, splitting between mutable and immutable parts is the essence of the Flyweight pattern: you can freely reuse the immutable part between all instances which need it in the same state.

You can also freely publish the immutable part to any interested party, without breaking any internals.

Additionally this may help if you need to deep-clone objects. The immutable part would be shared between clones.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
1

It is common for objects to be composed of other objects, and it is not unusual for some of those components to be immutable (e.g., for sharing common data across instances) while others are mutable.

I would not, however, go so far as to adopt a naming scheme which explicitly calls out the mutable and immutable components; stick to descriptive names that convey their purpose. From the outside looking in, mutability is typically considered for the entire object: either parts of it are mutable, in which case the object is considered mutable, or it is completely immutable. Moreover, an object's consumer typically cares more about what data is exposed by the object than where that data comes from or how it is structured internally, so bear this in mind when organizing and naming members.


As to your proposed design where you separate out the metadata, that makes perfect sense. It's not dissimilar from plain old Java objects: every object's metadata (its class definition) is separated from the instance data and exposed in a single place: getClass(). Note, however, that the name describes the (meta)data, and not its (im)mutability.

Mike Strobel
  • 25,075
  • 57
  • 69
1

I would suggest you divide your objects not based on the fact that they can be changed or not, but what they mean in the context of your class.

If you really want to mark immutable parts, annotations might even be better than changing the structure to facilitate the changeability of the data of the object.

Also don't forget, you might have mutable data that you hand out immutable copies of.

Keeping mutable / immutable variables in separate groups (with comments) makes sense but I really don't recommend changing what your object is (or consists of) based on a reasonably arbitrary attribute of it's data.

Joeblade
  • 1,735
  • 14
  • 22