By
using constructors, we can create objects to any class. There is also another
way to create objects to a class. By using static factory methods, you can
create instances to a class. Static factory method is a static method that
returns instance of this class.
For
example, following are some of the static factory methods provided by Java.
public
static Integer valueOf(int i) //Return Integer object
public
static Float valueOf(String s) throws NumberFormatException //Return Float
object
public
static Boolean valueOf(String s)//Return Boolean object
Let’s
see the advantages of defining static factory methods.
a. By providing the
meaningful name to static factory method, we can give meaningful context to the
developer (or) to the reader who is reading the source code.
b. By using static
factory methods we can control number of instances to a class
c. Static factory
methods provide flexibility that, it can return object of any subtype.
By
providing the meaningful name to static factory method, we can give meaningful
context to the developer (or) to the reader who is reading the source code.
Employee.java
public class Employee { private int id; private String firstName; private String lastName; private boolean permanentEmployee; private Employee(int id, String firstName, String lastName, boolean permanentEmployee) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.permanentEmployee = permanentEmployee; } public boolean isPermanentEmployee() { return permanentEmployee; } public void setPermanentEmployee(boolean permanentEmployee) { this.permanentEmployee = permanentEmployee; } 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; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public static Employee getPermanentEmployee(int id, String firstName, String lastName) { return new Employee(id, firstName, lastName, true); } public static Employee getContractEmployee(int id, String firstName, String lastName) { return new Employee(id, firstName, lastName, false); } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("Employee [id=").append(id).append(", firstName=").append(firstName).append(", lastName=") .append(lastName).append(", permanentEmployee=").append(permanentEmployee).append("]"); return builder.toString(); } }
Notify
above example, I provided two static factory methods to return permanent and
contract employee instances. By looking at following method signatures, user
can get an idea about the instance.
public
static Employee getPermanentEmployee(int id, String firstName, String
lastName);
public
static Employee getContractEmployee(int id, String firstName, String lastName);
Test.java
public class Test { public static void main(String args[]){ Employee permEmp = Employee.getPermanentEmployee(1, "Shanmukh", "Kummari"); Employee contractEmp = Employee.getContractEmployee(2, "Hari Krishna", "Gurram"); System.out.println(permEmp); System.out.println(contractEmp); } }
Output
Employee [id=1, firstName=Shanmukh, lastName=Kummari, permanentEmployee=true] Employee [id=2, firstName=Hari Krishna, lastName=Gurram, permanentEmployee=false]
By using
static factory methods we can control number of instances to a class
By
restricting access to the constructors of a class and by providing static
factory method to get the instance, you can control the number of instances to
the class at any given point of time.
Connection.java
public class Connection { private static Connection conn = new Connection(); private Connection() { } public static Connection getConnection() { return conn; } }
Test.java
public class Test { public static void main(String args[]) { Connection conn1 = Connection.getConnection(); Connection conn2 = Connection.getConnection(); System.out.println("(conn1 == conn2) : " + (conn1 == conn2)); System.out.println("conn1.equals(conn2) : " + conn1.equals(conn2)); } }
Output
(conn1 == conn2) : true conn1.equals(conn2) : true
Static
factory methods provide flexibility that, it can return object of any subtype.
ShapeFactory.java
public class ShapeFactory { public interface Shape { public default void print() { System.out.println("Default implementaiton of shape"); } } private static class Circle implements Shape { public void print() { System.out.println("I am inside circle"); } } private static class Square implements Shape { public void print() { System.out.println("I am inside Square"); } } private static class DefaultShape implements Shape { } public static Shape getShape(String shapeType) { switch (shapeType) { case "Square": return new Square(); case "Circle": return new Circle(); default: return new DefaultShape(); } } }
As
you see 'ShapeFactory' class, it exposes the 'Shape' interface by making it as
public and hides the implemebtations of Shape (Circle, Square, and DefaultShape) by making them
as private.
Test.java
public class Test { public static void main(String args[]) { ShapeFactory.Shape shape1 = ShapeFactory.getShape(""); ShapeFactory.Shape shape2 = ShapeFactory.getShape("Circle"); ShapeFactory.Shape shape3 = ShapeFactory.getShape("Square"); shape1.print(); shape2.print(); shape3.print(); } }
Output
Default implementaiton of shape I am inside circle I am inside Square
You may like
No comments:
Post a Comment