Factory Design Pattern
Pattern: The factory is a creational design pattern that allows you to replace direct object construction calls (using the
new
operator) with a call to a special factory method.1
If you have ever used a database in a Java application, you must have used Java Database Connectivity (JDBC) API. The JDBC has a class called DriverManager
which exposes a factory method getConnection
to connect to a database.
import java.sql.*;
public class Main {
public static void main(String[] args) throws SQLException {
final String URI = "jdbc:sqlite:./MyDatabase.db";
Connection conn = DriverManager.getConnection(URI);
// do something with the connection
conn.close();
}
}
In the example of JDBC API, DriverManager
creates Connection
objects (instead of using new
keyword with Connection
). So why would we want this? Why not use a constructor to make Connection
objects?
Well, under the hood, the DriverManager
will find the database driver (from the URI
) and call the connect()
method of the driver which in turn will return a concrete implementation of Connection
class (that is, a subclass of the Connection
class that is specialized to work with database of interest). This eliminates the need for you to specify concrete implementations of Connection
in your code. "How so?" you ask! Well, read on!
In the example above, I'm trying to connect to a SQLite database. Let's assume the SQLite JDBC driver has a class called SQLiteConnection
which implements Connection
2; we could write
Connection conn = new SQLiteConnection("./MyDatabase.db");
The code above would require us to "know" about (existence and the use of) SQLiteConnection
, to "import" it in our source code, properly call it (with required arguments), etc. SQLiteConnection
is then a "dependency" in our code. Using the DriverManager.getConnection
eliminates this dependency. Moreover, since all DriverManager.getConnection
takes is a string (URI
), we can connect to a different database during runtime.
Using factory pattern, the client code asks the factory to make (use) an implementation The client code does not decide which implementation to use and therefore it is not coupled to it.
The factory is one of the most widely used patterns in Java libraries!
When to use this pattern? Use the Factory pattern when you want to provide users of your library or framework with a way to extend its internal components, allowing your clients to decouple their application from concrete implementations of your framework.
Advantage: Factory pattern removes the instantiation of actual implementation classes from client code. Factory pattern makes client code more robust, less coupled, and easy to extend.
1 Factory, Factory Method and Abstract Factory are all design patterns with subtle differences; the underlying idea of all is to let other objects make objects for you.
2 I don't know if there is an SQLiteConnection
class but let's assume it is the case for the sake of the example.