DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • User-Friendly API Publishing and Testing With Retrofit
  • MCP Is Coming to Your Desktop Applications
  • Testing Business Programs Without Constructing Domain Objects
  • Beyond SOLID: Embracing CUPID for Modern Software Craftsmanship

Trending

  • ScyllaDB in Enterprise Java: High-Performance NoSQL With Eclipse JNoSQL
  • Taming Parameter Sniffing in SQL Server 2022 With PSP Optimization
  • Evals in CI: How to Catch Agent Regressions Before Production Does
  • Why Spark Executors Leave Cores Idle on YARN: A Packing Model for Executor Sizing

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

  1. DZone
  2. Coding
  3. Languages
  4. Immutability Through Interfaces

Immutability Through Interfaces

By 
Andy Gibson
·
Nov. 15, 14 · Interview
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
14.1K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

It is often desirable to have immutable objects, objects that cannot be modified once constructed. Typically, an immutable object has fields that are declared as final and are set in the object constructor. There are getters for the fields, but no setters since the values cannot be saved. Once created, the object state doesn’t change and the objects can be shared across different threads since the state is fixed. There are plenty of caveats to that statement, for example if you have a list, while the list field reference may be final, the list itself may be able to change and have values added and removed which would spoil the immutability.

Achieving this state can often be difficult because we rely on a number of tools and frameworks that may not support immutability such as any framework that builds an object by creating it and then setting values on it.

However, one way around this would be to take a mutable object and make it immutable through interfaces. We do this by creating an interface that represents all the getters for an object, but none of the setters.

Given a domain entity of a person with an id, first and last name fields we can define an immutable interface :

public interface ImmutablePerson {
    public int getId();
    public String getFirstName();
    public String getLastName();
}

We can then implement this interface in our person class :

public class PersonEntity implements ImmutablePerson {
    private int id;
    private String firstName;
    private String lastName;
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getFirstName() {
        return firstName;
    }
 
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

Our API deals with the PersonEntity class internally, but exposes the object as the ImmutablePerson only.

public ImmutablePerson loadPerson(int id) {
    PersonEntity result = someLoadingMechanism.getPerson(id);
    result.setxxxxx(somevalue); //we can change it internally
    return result; //once it has been returned it is only accessed as an immutable person
}

To return a mutable instance for modification, you can return the PersonEntity. Alternatively, you can add aMutablePerson interface with just the setters and implement that. Unless you want to keep casting between the Immutable/Mutable types, the MutablePerson interface can extend the ImmutablePerson interface so the writable version is also readable.

public interface MutablePerson extends ImmutablePerson {
    public void setId(int id) {
    public void setFirstName(String firstName);
    public void setLastName(String lastName);
}


Granted, someone can easily cast the object to a PersonEntity or MutablePerson and change the values, but then, you can also change static final variables with reflection if you wanted to. The ability to cast the object to make it writable only could be an internal-use only feature.

This mechanism can be used to return immutable objects from persistence layers. There are some caveats with certain ORM tools since they use lazy loading mechanisms that would break the immutability. Underneath the interface it is still a mutable object. With some additional code, you could create immutable collections by wrapping the underlying collections in read only collections and returning them to the user.

Some of the JVM benefits of immutability granted upon variables marked as final would not be given to this type of solution since the underlying variables are not final or immutable.

Interface (computing) Object (computer science)

Published at DZone with permission of Andy Gibson. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • User-Friendly API Publishing and Testing With Retrofit
  • MCP Is Coming to Your Desktop Applications
  • Testing Business Programs Without Constructing Domain Objects
  • Beyond SOLID: Embracing CUPID for Modern Software Craftsmanship

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook