This article is participating in the Java Theme Month – Java Debug Notes Event, see the event link for details

preface

Static factory method, have you heard of it? In the process of learning Java, we will encounter a lot of conceptual methods, so how to learn, this time, we will output the relevant learning methods.

Problem of repetition

The origin of the problem comes from the question, which is, what is the static factory method?

Problem solving

We avoid directly accessing database connections because they are resource intensive. So getDbConnection, if we are below the limit, we will use the static factory method to create the connection. Otherwise, it attempts to provide an “alternate” connection, fails if none exists, and displays an exception.

public class DbConnection{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection(a){
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection(a){

     if(totalConnections < MAX_CONNS){
       return new DbConnection();

     }else if(availableConnections.size() > 0){
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;

     }else {
         throw newNoDbConnections(); }}public static void returnDbConnection(DbConnection dbc){
     availableConnections.add(dbc);
     / /...}}Copy the code

The static factory method pattern is a kind of wrapper object creation. If there are no factory methods, you simply call the constructor of the class directly: Foo x = new Foo(). Using this pattern, you can instead call the factory method: Foo x = foo.create (). Constructors are marked private, so they can only be called from within the class, and factory methods are marked static so that they can be called without having the object in the first place.

This model has some advantages. One is that the factory can choose from a number of subclasses (or implementers of interfaces) and return. This way, callers can specify the desired behavior through parameters without having to know or understand the potentially complex class hierarchy.

As Matthew and James point out, another advantage is controlling access to limited resources, such as connections. This is a way to implement a pool of reusable objects – rather than building, using, and dismantling objects, it may make more sense to build them once and recycle them if construction and destruction are expensive processes. The Factory method can return an existing, unused instantiated object (if any), construct an object if the object count is below some lower threshold, or throw an exception or return null if it is above the upper threshold.

According to the Wikipedia article, multiple factory methods also allow for different interpretations of similar parameter types. Typically, constructors have the same name as classes, which means you can only have one constructor with a given signature. The factory is not that constrained, which means you can have two different methods that accept the same parameter type:

Coordinate c = Coordinate.createFromCartesian(double x, double y)

Coordinate c = Coordinate.createFromPolar(double distance, double angle)

Increase readability through static factory methods.

conclusion

It all boils down to maintainability. Whenever an object is created using the new keyword, the code being written is coupled to the implementation.

The factory pattern lets you separate how objects are created from how they are processed. When you use constructors to create all objects, you’re actually using hard coding to wire code that uses the object to the implementation. The code that uses your object “depends on” that object. On the surface, this might not seem like a big deal, but when an object changes (you want to change the signature of the constructor, or subclass the object), you have to go back and rewire it anywhere.