Factory and Abstract Factory Design Patterns

Factory Design Pattern

Factory Design Pattern is one of the simple Design Pattern. A factory takes responsibility to create objects. Thus removes logic duplication and creational logics from code. So, lets start with code.

public class DocumentFactory {
    private String documentType;

    public DocumentFactory(String documentType) {
        this.documentType = documentType;
    }

    public Document createDocument() {

        if (documentType.equals("ACCESS")) {
            return new AccessDocument();
        } else if (documentType.equals("EXCEL")) {
            return new ExcelDocument();
        } else if (documentType.equals("WORD")) {
            return new WordDocument();
        }

        return null;
    }
}

Another variation of GoF Factory method is:

public class DocumentFactory {

    public Document createDocument(String documentType) {

        if (documentType.equals("ACCESS")) {
            return new AccessDocument();
        } else if (documentType.equals("EXCEL")) {
            return new ExcelDocument();
        } else if (documentType.equals("WORD")) {
            return new WordDocument();
        }

        return null;
    }
}

It allows client to create different type of objects with same factory.

Problem with Factory Pattern

DocumentFactory wordDocumentFactory = new DocumentFactory("WORD");
Document wordDocument = wordDocumentFactory.createDocument();

WriterFactory writerFactory = new WriterFactory("ACCESS");
Writer writer = writerFactory.createWriter();

wordDocument.addWriter(writer);
document.write();

So, a Access Writer can be attached with a Word Document which is undesirable if objects are interdependable. Abstract Factory Pattern solves this.

Abstract Factory Pattern

public class abstract DocumentFactory {
    abstract public Document createDocument();
    abstract public Writer createWriter();
}

public class WordDocumentFactory extends DocumentFactory {

    public Document createDocument() {
        return new WordDocument();
    }

    public Writer createWriter() {
        return new WordWriter();
    }
}

public class AccessDocumentFactory extends DocumentFactory {
    ...
}

public class ExcelDocumentFactory extends DocumentFactory {
    ...
}

public class DocumentFactoryBuilder {
    public static DocumentFactory createDocumentFactory(String documentType) {
        if (documentType.equals("ACCESS")) {
            return new AccessDocumentFactory();
        } else if (documentType.equals("EXCEL")) {
            return new ExcelDocumentFactory();
        } else if (documentType.equals("WORD")) {
            return new WordDocumentFactory();
        }

        return null;
    }
}

Now client will use this as:

DocumentFactory wordDocumentFactory
        = DocumentFactoryBuilder.createDocumentFactory("WORD");
Document document = wordDocumentFactory.createDocument();
Writer writer = wordDocumentFactory.createWriter();
document.addWriter(writer);
document.write();

Abstract Factory Pattern with Template Pattern

public class abstract DocumentFactory {
    abstract public Document createDocument();
    abstract public Writer createWriter();

    // Template Method
    public Document getDocument() {
        Document document = createDocument();
        Writer writer = createWriter();
        document.addWriter(writer);
        return document;
    }
}

public class WordDocumentFactory extends DocumentFactory {

    protected Document createDocument() {
        return new WordDocument();
    }

    protected Writer createWriter() {
        return new WordWriter();
    }

}

public class AccessDocumentFactory extends DocumentFactory {
    ...
}

public class ExcelDocumentFactory extends DocumentFactory {
    ...
}

public class DocumentFactoryBuilder {
    // Factory Method
    public static DocumentFactory createDocumentFactory(String documentType) {
        if (documentType.equals("ACCESS")) {
            return new AccessDocumentFactory();
        } else if (documentType.equals("EXCEL")) {
            return new ExcelDocumentFactory();
        } else if (documentType.equals("WORD")) {
            return new WordDocumentFactory();
        }

        return null;
    }
}

Now client will use this as:

DocumentFactory wordDocumentFactory
        = DocumentFactoryBuilder.createDocumentFactory("WORD");
Document document = wordDocumentFactory.getDocument();
document.write();

One thought on “Factory and Abstract Factory Design Patterns

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s