Understanding the Factory Pattern: Simple Factory, Factory Method, and Abstract Factory with Java Examples
This article explains the factory design pattern, covering simple factory, factory method, and abstract factory variants, their typical use cases such as document parsing and automated testing, and provides complete Java code examples illustrating each implementation.
Design patterns are essential skills for writing good code; the factory pattern provides reusable solutions for object creation problems in object‑oriented design. This article introduces the factory pattern and its three main forms.
Simple Factory Pattern belongs to the creational patterns and hides the object‑creation logic behind a common interface. It is useful when the number of products is small, such as parsing a Word2007 document where different parsers (Paragraph, Table, Draw) are created based on the XML structure. The following Java example shows a simple factory that creates parser instances based on an integer constant.
public class DocxParser {
// Abstract product: common interface for all parsers
public interface IParser {
void process(String entity);
}
// Concrete products
static class Paragraph implements IParser {
public void process(String entity) {
System.out.println("Parsing Paragraph...");
}
}
static class Table implements IParser {
public void process(String entity) {
System.out.println("Parsing Table...");
}
}
static class Draw implements IParser {
public void process(String entity) {
System.out.println("Parsing Draw...");
}
}
// Constants for entity types
static final class Const {
static final int ENTITY_PARAGRAPH = 0;
static final int ENTITY_TABLE = 1;
static final int ENTITY_DRAW = 2;
}
// Simple factory
static class ParserFactory {
public static IParser createParser(int kind) {
switch (kind) {
case Const.ENTITY_PARAGRAPH: return new Paragraph();
case Const.ENTITY_TABLE: return new Table();
case Const.ENTITY_DRAW: return new Draw();
}
return null;
}
}
// Simple usage example
public static void main(String[] args) {
// entity represents document.xml content (omitted)
// Parse paragraph
ParserFactory.createParser(Const.ENTITY_PARAGRAPH).process(entity);
// Parse table
ParserFactory.createParser(Const.ENTITY_TABLE).process(entity);
// Parse draw
ParserFactory.createParser(Const.ENTITY_DRAW).process(entity);
}
}Factory Method Pattern solves the violation of the Open/Closed principle in simple factories by defining an interface for creating objects and letting subclasses implement the creation. It is suitable when product structures become complex, such as browser‑automation testing where different drivers (Chrome, Firefox, Safari) need separate initialization. The example below demonstrates abstract driver, concrete driver classes, and factories that produce them.
public class FactoryDemo {
// Abstract product: common driver interface
abstract static class Driver {
abstract void process();
}
// Concrete drivers
static class ChromeDriver extends Driver {
@Override void process() { System.out.println("ChromeDriver process"); }
}
static class FirefoxDriver extends Driver {
@Override void process() { System.out.println("FirefoxDriver process"); }
}
static class SafariDriver extends Driver {
@Override void process() { System.out.println("SafariDriver process"); }
}
// Abstract factory interface
public interface AbstractFactory {
Driver create();
}
// Concrete factories
static class ChromeDriverFactory implements AbstractFactory {
@Override public Driver create() { return new ChromeDriver(); }
}
static class FirefoxDriverFactory implements AbstractFactory {
@Override public Driver create() { return new FirefoxDriver(); }
}
static class SafariDriverFactory implements AbstractFactory {
@Override public Driver create() { return new SafariDriver(); }
}
// Client usage
public static void main(String[] args) {
AbstractFactory chromeFactory = new ChromeDriverFactory();
Driver chrome = chromeFactory.create();
chrome.process();
AbstractFactory firefoxFactory = new FirefoxDriverFactory();
Driver firefox = firefoxFactory.create();
firefox.process();
}
}Abstract Factory Pattern further extends the factory method by allowing a factory to create families of related objects. It is ideal for scenarios with many product types across multiple platforms, such as a membership system where different membership levels (Normal, Monthly) have platform‑specific implementations (iOS, Android, PC). The following code defines abstract products, concrete products, an abstract factory, and concrete factories for each platform.
// Abstract product
public interface Vip {}
// Concrete products
public class NormalVip implements Vip {}
public class MonthlyVip implements Vip {}
// Platform‑specific products
public class IOSNormalVip extends NormalVip {}
public class AndroidNormalVip extends NormalVip {}
public class PCNormalVip extends NormalVip {}
public class IOSMonthlyVip extends MonthlyVip {}
public class AndroidMonthlyVip extends MonthlyVip {}
public class PCMonthlyVip extends MonthlyVip {}
// Abstract factory
public interface AbstractVipFactory {
Vip createNormalVip();
Vip createMonthlyVip();
}
// Concrete factories
public class IOSVipFactory implements AbstractVipFactory {
@Override public Vip createNormalVip() { return new IOSNormalVip(); }
@Override public Vip createMonthlyVip() { return new IOSMonthlyVip(); }
}
// (Other platform factories omitted for brevity)
// Client example
public class Client {
public static void main(String[] args) {
IOSVipFactory iosFactory = new IOSVipFactory();
Vip normal = iosFactory.createNormalVip();
// use the vip instance
}
}By studying these three real‑world cases, readers can understand when to apply each factory variant: use Simple Factory for straightforward, limited product sets; Factory Method when product hierarchies grow and the Open/Closed principle must be respected; and Abstract Factory when multiple related product families need to be created across different platforms.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
