Search code examples
javaeffective-java

Static Factory Methods - return any subtype


I'm reading the book Effective Java and Joshua Bloch, in chapter 2, said:

A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.

I don't understand how to use this concept in practice?

Can someone give me an example?


Solution

  • 1. Hiding from the client (better encapsulation) of object creation

    Here's an example of a so-called "Simple Factory" (a.k.a. parametrized factory):

    public class UserFactory {
    
        public static User newUser(UserEnum type){
            switch (type){
                case ADMIN: return new Admin();
                case STAFF: return new StaffMember();
                case CLIENT: return new Client();
                default:
                    throw new IllegalArgumentException("Unsupported user. You input: " + type);
            } 
        }
    }
    

    The point of encapsulating object creation into a static factory is that the users don't know (and don't care) how an object gets created:

    // client code - give me an admin object, 
    // don't care about the inner details of how it gets constructed
    User admin = UserFactory.newUser(ADMIN); 
    

    2. Flexibility to swap out implementations without breaking client code

    Consider this static factory method:

    // swap out with LinkedList later if you like, 
    // it won't break the 100 places that invoke this method
    public static List<String> getMyList(){
        return new ArrayList<>(); 
    }
    

    Don't like any of the standard list implementations and you create your own some time later?

    public class MyMuchBetterList<E> extends AbstractList<E> implements List<E> {
    
        // implementation
    }
    

    No problem, you can still swap inside the static factory without affecting those using getMyList:

    public static List<String> getMyList(){
            return new MyMuchBetterList<>(); // compiles and works, subtype of list
        }