1

I do know that the best practice these days is to model immutable classes in Java. An ex: below

// It makes sense to model this in an immmutable fashion
class 2DPoint {
  private int x;
  private int y;
  2DPoint(int x, int Y) {
    this.x = x;
    this.y = y;
  }
  public Int getXCoordinate() {
    return this.x;
  }
  public Int getYCoordinate() {
    return this.y;
  }
}

But how do you model a real world mutable object like a Car as a mutable class. If you modelled it as an immutable class like ImmutableCar given below, you'd have different object instances referencing the same real world car at different ticks of time. This feels like a violation of the inspirations for object oriented design where you let real world objects almost guide how you think about software

The other reason to model something as a mutable class is if your mutable constructor parameters that you store as private variables are too expensive to defensively copy

 public Car {
   private int fuel;
   ..... 
   public int addFuel(int amount) {
     this.fuel += amount;
     return this.fuel;
   } 
 }
 public ImmutableCar {
   private final int fuel;
   public ImmutableCar() {
     this.fuel = 0;
   } 
   public ImmutableCar(int fuel) {
     this.fuel = fuel;
   }
   ...
   public ImmutableCar addFuel(int amount) {
     return new ImmutableCar(fuel + amount);
   }

 }

However the dangers of mutable classes are:

  • Concurrency is a lot harder if you have multiple threads trying to update the same object. You'll need to think of mutual exclusion and introduce locks
  • If you have multiple classes holding a reference to a mutable object, you lose local reasoning within a class. Each class holding a reference loses its ability to control the state lifecycle of the mutable object and a programmer can't reason locally about invariants. They'd need to be aware of the other classes holding references, and this breaks modularity and introduces coupling in a sense.

So given these tradeoffs, is it always preferable to model classes in an immutable fashion, even if they represent real world mutable objects?

3
  • 1
    Does this answer your question? At what point do immutable classes become a burden?
    – gnat
    Commented Jul 29, 2022 at 18:04
  • A "best practice" is not a law of the universe - it's a rule of thumb, a heuristic, that was motivated by some underlying reasoning, by some set of needs and constraints. No best practice is beneficial in every case imaginable. The recommendation is not to eradicate all mutable classes, it's to prefer immutability. If the motivation behind the "best practice" doesn't apply in your particular case, or if it flatly contradicts the constraints you face, than applying that practice in that situation is bad. You have to find a balance that makes sense for the language you're using. Commented Jul 29, 2022 at 18:51
  • In languages like Java and C#, good candidates for immutable types are things that are relatively small and cheep to create (like value types that are created on the stack) - so that you can have behavior (or change) expressed over several distinct copies. Also, things that might live on the heap, but aren't created that often (they don't appear, directly or indirectly, in tight loops and such) - where you can use the constructor to "configure" the behavior for a particular use case, then pass the object along as an immutable "encapsulated decision", that things can make use of. Commented Jul 29, 2022 at 19:00

2 Answers 2

1

The goal of object-oriented design is to model abstract behaviors and business processes, not real world things.

That being said, a vehicle is mutable in the real world. Any single vehicle is a "single instance". Adding fuel to the tank does not create a new car. When modeling abstract behaviors or business processes, however, you are not modeling a car, you are modeling something else. The decision to make a class mutable or immutable is not based on the "real world thing". Instead, the decision is based on how the programmer needs to use each object in order to accomplish a higher level behavior or business process.

If a Car represents a real car in a traffic simulation, mutability is desirable. If that Car gets into a wreck, you don't want two cars: the non-wrecked one and the wrecked one.

Consider a different use case where a Car represents plans to build a real car — the "real" car doesn't exist yet. In this case it might be desirable to have an immutable object. Each operation on the Car produces a new, mutated version of the previous state. This might be desirable in cases where you need to compare two different states, or the code runs in a highly concurrent environment. And these are just a few examples.

Benefits of immutability include:

  • The code is easier to understand, because nothing changes after initialization.
  • The code is inherently thread-safe (because nothing changes after initialization).
    • You can allow state to be modified if the modification produces a new object.

The decision to make a class immutable is based on the requirements necessary to complete some business process, not because a Car needs to represent a real rubber-wheels-on-the-ground vehicle. A class is an abstraction, and immutability is a tool for programmers to use if the tool fits the job.

Some additional reading on an older question at StackOverflow: Why do we need immutable class?.

1

Immutability is more about our relationship with memory than with the real world we're modeling. Specifically it's about shared mutable state and the ability to update that in an atomic way.

For example, your post is represented with an immutable string. Does that mean you can't change it? No, there's an edit link right there at the bottom. You can change it at any time. What you can't do is be halfway done changing it when I decide to load it and leave me with a mangled post. That is prevented by the server writing the new version of your post in new memory at a new address. The whole post can't easily be updated atomically. But the address of your post can. Now I say address but when we're talking about Java objects they like it better when I call it a reference.

This may seem weird but it's no more weird then animated cartoons. Someone draws a static unmoving picture of a rabbit arguing with a duck about what hunting season it is and nothing moves, until they show you the next unmoving picture.

Yes it's an illusion. But it's the safest way to deal with change that must happen together.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.