What is a factory and why would I want to use one?
Are you familiar with JDBC? It's one and all (abstract) factory. It's a good real world example.
// Factory method. Loads the driver by given classname. It actually returns a
// concrete Class<Driver>. However, we don't need it here, so we just ignore it.
// It can be any driver class name. The MySQL one here is just an example.
// Under the covers, it will do DriverManager.registerDriver(new Driver()).
Class.forName("com.mysql.jdbc.Driver");
// Abstract factory. This lets the driver return a concrete connection for the
// given URL. You can just declare it against java.sql.Connection interface.
// Under the covers, the DriverManager will find the MySQL driver by URL and call
// driver.connect() which in turn will return new ConnectionImpl().
Connection connection = DriverManager.getConnection(url);
// Abstract factory. This lets the driver return a concrete statement from the
// connection. You can just declare it against java.sql.Statement interface.
// Under the covers, the MySQL ConnectionImpl will return new StatementImpl().
Statement statement = connection.createStatement();
// Abstract factory. This lets the driver return a concrete result set from the
// statement. You can just declare it against java.sql.ResultSet interface.
// Under the covers, the MySQL StatementImpl will return new ResultSetImpl().
ResultSet resultSet = statement.executeQuery(sql);
You do not need to have a single line of JDBC driver specific import
in your code. You do not need to do import com.mysql.jdbc.ConnectionImpl
or something. You just have to declare everything against java.sql.*
. You do not need to do connection = new ConnectionImpl();
yourself. You just have to get it from an abstract factory as part of a standard API.
If you make the JDBC driver class name a variable which can be configured externally (e.g. properties file) and write ANSI compatible SQL queries, then you do not ever need to rewrite, recompile, rebuild and redistribute your Java application for every single database vendor and/or JDBC driver which the world is aware of. You just have to drop the desired JDBC driver JAR file in the runtime classpath and provide configuration by some (properties) file without the need to change any line of Java code whenever you want to switch of DB or reuse the app on a different DB.
That's the power of interfaces and abstract factories.
Another known real world example is Java EE. Substitute "JDBC" with "Java EE" and "JDBC driver" with "Java EE application server" (WildFly, TomEE, GlassFish, Liberty, etc).