Immutable class / object, private constructor, factory method

Already read how to make a class immutable by following these steps

  • Do not provide setter methods - methods that modify fields or objects referenced by fields.
  • Make all fields final and private.
  • Do not let subclasses override methods. The easiest way to do this is to declare the class final. A more sophisticated approach is to make the constructor private and build instances in factory methods.
  • If links to mutable objects are included in the instance fields, do not allow these objects to be modified:
    a. Do not provide methods that modify mutable objects.
    b. Do not use references to mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies and store links to copies. Similarly, create copies of your internal mutable objects when necessary, to avoid the originals returning to your methods.

I'm not sure that I clearly understand the private constructor utility and the factory method in the context of immutability. If I make the class final, basically I close all the paths of any other class that extends it. How a more complex approach is formulated

I saw a private constructor, the factory method in the Singleton template, which makes sense. But when we talk about the immutability of an object, do we also restrict building an object / creating an instance when we mention the private constructor and static factory methods?

+6
source share
7 answers

IMMUTABILITY is very useful for concurrency, as it avoids creating the various invariants that are possible in a streaming environment.

FACTORY METHODS are just a naming convention, as they are more detailed to read and easy to understand from their user name. For example: the copyOf() method would make more sense than creating a copy constructor. As Joshua Bloch said in Effective Java

PRIVATE CONSTRUCTORS . They have their own applications in templates such as Singleton, but have their own limitations.

+1
source

I think the big problem here is future refactoring. Suppose in a later version you find that it would make something a lot easier if you could break up some new special case of MyClass into a subclass of MySpecialClass.

If MyClass was a modified class with an open constructor, you could just do this and inform users about new features to create a new MySpecialClass. Existing applications are not affected.

If MyClass has a private constructor and factory method, no problem. You declare MySpecialClass nested in MyClass, also using a private constructor. Add and / or modify factory methods to choose what to create, but make sure that existing calls continue to work compatible.

What would you do if MyClass were immutable and final, but had an open constructor?

+1
source

Yes you are right. It makes no sense to make the constructor private. By doing this, we restrict instantiation, which is not a desirable scenario for immutability.

The example on the sun site does not create the private constructor http://docs.oracle.com/javase/tutorial/essential/concurrency/syncrgb.html

0
source

First, there are several reasons why an immutable class should not usually be overestimated, you can find it here .

However, creating a private constructor is just one way to prevent the class from being overrated. What for? Since in a subclass, each constructor (implicitly) calls super() , the default constructor of the base class. But if you make this constructor private, the subclass cannot call it and therefore cannot override the base class. This approach is very suitable if you want to control the total number of instances of a particular class, for example, in the case of single games.

0
source

Some of my own results from Effective Java , paragraph 15, insertion of relevant statements from the same

β€œRecall that in order to guarantee immutability, a class should not allow itself to be subclassed. Usually this is done by making the class final, but there is another, more flexible way to do this. An alternative to creating an indispensable final for a class is to create all its private or batch-private constructors, and also add public static plants to the place of public designers (clause 1).

Although this approach is not commonly used, it is often the best alternative. this is the most flexible as it allows the use of multiple package-private classes implementation. . An immutable class is effective for its customers who are outside its package because it is not possible to extend a class that comes from another package and that does not have an open or protected constructor. Besides the flexibility of several implementation classes, this approach allows you to tune the performance of the class in subsequent releases, improving the object caching capabilities of static plants.

"

static factory and constructor benefits are discussed

0
source

The idea of ​​a private constructor is that you want to hide an immutable implementation of class data, allowing you to create a new instance with different data of the same internal type.

for instance

 public class Temperature { private readonly double temperatureInCelsius; public Temperature(string temperatureInCelsius) { this.temperatureInCelsius = System.Convert.ToDouble(temperatureInCelsius); } private Temperature(double temperatureInCelsius) { this.temperatureInCelsius = temperatureInCelsius; } public Temperature AddCelsius(string temperatureToAddInCelsius) { return new Temperature(System.Convert.ToDouble(temperatureToAddInCelsius) + temperatureInCelsius); } public void PrintCelsius(Display display) { display.Print(temperatureInCelsius); } public void PrintFarenheit(Display display) // ... etc } 

Ignoring the stupidity of the example, if your requirements are that the class can be built from a string representing the temperature. The way in which it actually keeps the temperature can be changed and is a detail of the implementation. This class can be changed to use float, strings, double, ints, etc. This method maintains immutability while providing flexibility in implementation. Obviously, this becomes much more powerful when you wrap more complex objects, such as collections, dictionaries, etc.

0
source

This is because, with the help of a private constructor, we cannot make it a subclass and thereby limit all the paths of any other class that extends it. It is sophisticated because it has its own limitations / difficulties, for example, in a single template.

-1
source

All Articles