Search code examples
javaobjectcloneimmutability

Is it better to modify an object directly or to return a modified clone of the object?


The problem is I can't modify an object I'm writing from inside itself and thus made a clone that I modify and return. However, in other functions I directly modify the object calling the method. I would like, and people have recommended, to keep things consistent and so the user can do anything they like with the returned clone without modifying the actual object.

I HAVE to return a modified clone of the object in certain functions because there's no way around it (that I'm aware of). Along with the question in the title, is it better to have a consistent way of doing things (causing me to return clones for even the slightest change) or is it okay if I have different ways to respond to the user in the same class?

[Edit] Is it better to do this:

 public Image fillWithColor(Color fillColor) {
    Image newImage = new Image(this.getWidth(), this.getHeight(), this.getType());

    for (int x = 0; x < this.getWidth(); x++) {
        for (int y = 0; y < this.getHeight(); y++) {
            newImage.setPixel(x, y, fillColor.getRGB());
        }
    }

    return newImage;
}

or this:

public void fillWithColor(Color fillColor) {
    for (int x = 0; x < this.getWidth(); x++) {
        for (int y = 0; y < this.getHeight(); y++) {
            this.setPixel(x, y, fillColor.getRGB());
        }
    }
}

Solution

  • A mega-trend is to treat as much data as possible as read-only, for various important reasons. Even databases do this today.

    You obviously have recognized that uncontrolled modification of data can get you into trouble. Very good. Try to design your data as immutable objects, and many things will be much easier in the long run. Just note that certain data structures in Java are inherently mutable (arrays, hash-tables, and so on), and are meant and expected to get mutated.

    In the exmple above, I'd choose the first variant. Why? It might cost a few microseconds and some RAM to copy the image, instead to update in-place. But you can keep the old image around, and depending on your application, this may be beneficial. Also, you could color the same image with 10 different fill colors in 10 different threads in parallel, and there would be no locking problems.

    That being said, it is still not possible to answer your question like "It is always better ...". It depends on your problem, on your environment, programming language, libraries you are using and many factors more.

    So let's say, immutable data are preferrable most of the time, unless there are serious reasons against it. (Saving a few micro-seconds on execution time is usually not a serious reason.)

    To put it differently, there should be good reasons to make a data type mutable, while immutability should be the default. Unfortunately, Java is not the language that supports this approach, to the contrary, everything is mutable by default, and it takes some effort to make it different.