Now, ultimately we start discussing design patterns - really buzzwords.

Singleton

Singleton pattern is to ensure the unique instance of some class in a JVM.

class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {

    }

    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }

        return instance;
    }

    public void doSomething() {
        System.out.println("doSomething(): Singleton does something!");
    }
}

// DCL for thread safe
class DoubleCheckedLockingLazySingleton {
    private static DoubleCheckedLockingLazySingleton instance;

    private DoubleCheckedLockingLazySingleton() {
        System.out.println("Singleton(): Initializing Instance");
    }

    public static DoubleCheckedLockingLazySingleton getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckedLockingLazySingleton.class) {
                if (instance == null) {
                    System.out.println("getInstance(): First time getInstance was invoked!");
                    instance = new DoubleCheckedLockingLazySingleton();
                }
            }
        }

        return instance;
    }

    public void doSomething() {
        System.out.println("doSomething(): Singleton does something!");
    }
}

class EagerSingleton {
    private final static EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {
        System.out.println("Singleton(): Initializing Instance");
    }

    public static EagerSingleton getInstance() {
        return instance;
    }

    public void doSomething() {
        System.out.println("doSomething(): Singleton does something!");
    }
}

You can see there is a DCL(Double-checked-Locking) implementation for lazy initialization. But this clever-seeming may not work. Please refer to Double-checked locking: Clever, but broken

Factory

Factory pattern is very easy to understand.

classic factory

Factory Implementation - UML Class Diagram

interface Product {}

class ConcreteProduct implements Product {
}

class SimpleFactory {

    public static Product createProduct() {
        Product product = new ConcreteProduct();
        // do other tasks for initialization
        return product;
    }
}

conditional switch factory

class AnotherConcreteProduct implements Product {}

class ConditionalFactory {
    public static Product createProduct(String productId) {
        Product product = null;
        if ("concreteProduct".equals(productId)) {
            product = new ConcreteProduct();
        }
        if ("anotherConcreteProduct".equals(productId)) {
            product = new AnotherConcreteProduct();
        }

        // do other tasks for initialization
        return product;
    }
}

class registry factory

class ProductClassRegistryFactory {
    private HashMap<String, Class<Product>> registry = new HashMap();

    public void registerProduct(String productID, Class productClass) {
        registry.put(productID, productClass);
    }

    public Product createProduct(String productID) throws Exception {
        Class clazz = (Class) registry.get(productID);
        Constructor productConstructor = clazz.getDeclaredConstructor(new Class[]{String.class});
        return (Product) productConstructor.newInstance(new Object[]{});
    }
}

instance registry factory

// For registeration on its own
abstract class SelfRegisterableProduct implements Product {
    public abstract Product createProduct();
}

class OneProduct implements Product {
    static {
        new ProductRegistryFactory().registerProduct("ID1", new OneProduct());
    }

    public OneProduct createProduct() {
        return new OneProduct();
    }
}

class ProductRegistryFactory {
    private HashMap<String, Product> registry = new HashMap();

    public void registerProduct(String productID, Product p) {
        registry.put(productID, p);
    }

    public Product createProduct(String productID) {
        return ((SelfRegisterableProduct) registry.get(productID)).createProduct();
    }
}

Factory Method

Factory method is really no difference as a variant of factory pattern. It makes the factory as abstract class instead of implementing the creation logic in itself.

Factory Method Implementation - UML Class Diagram

A concrete factory is responsible for a kind of concrete product.

Abstract Factory

Simply speaking, abstract factory is responsible for the creation of a family of products. So it provides multiple methods to create several related products of different types.

Abstract Factory Implementation - UML Class Diagram