Mastering Factory Patterns: Simple, Factory Method & Abstract Factory Explained
This article revisits the core creational patterns—Simple Factory, Factory Method, and Abstract Factory—explaining their motivations, role divisions, basic concepts, detailed implementations with Java code, and comparative insights to help developers choose the right pattern for scalable object creation.
Why Need a Factory
Systems constantly create objects, often using new(). Direct creation couples core logic with object creation details. The factory pattern decouples non‑core creation logic from the main flow, allowing objects to be obtained via factory methods.
Roles in Factory Patterns
Abstract Product (always present)
Concrete Product (always present)
Abstract Factory (present in Factory Method and Abstract Factory)
Concrete Factory (always present)
Context (always present) – uses the factory to obtain objects
Basic Understanding of Factories
A factory method receives parameters and returns a corresponding product object; it is essentially a producer of products.
The returned type is the abstract product, enabling different concrete products to be created based on conditions.
Simple Classification of Factory Patterns
1. Simple Factory
Products have an abstract layer, but the factory does not. A single factory creates product types based on input parameters. Adding a new product family requires modifying the factory, violating the Open‑Closed Principle.
2. Factory Method
Both products and factories have abstract layers; each factory creates a single product type. Adding new products only requires a new factory, adhering to the Open‑Closed Principle.
3. Abstract Factory
Products and factories both have abstract layers, and a factory can create multiple product types (e.g., CPU, motherboard, graphics card). It solves the problem of switching entire product families.
Simple Factory Detailed
Only one factory class exists without an abstract layer.
Example: CpuFactory creates ACpu, BCpu, etc. Adding CCpu requires changing the factory method.
package com.taobao.migao.pattern.factory.simplefactory;
/**
* Product abstract interface: CPU
*/
public interface Cpu {
void calculate();
} package com.taobao.migao.pattern.factory.simplefactory;
/**
* Concrete product: A CPU
*/
public class ACpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is A cpu");
}
} package com.taobao.migao.pattern.factory.simplefactory;
/**
* Concrete product: B CPU
*/
public class BCpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is B cpu");
}
} package com.taobao.migao.pattern.factory.simplefactory;
/**
* Simple factory class: CPU factory
*/
public class CpuFactory {
public static Cpu createCpu(Class classType) {
if (classType.getName().equals(ACpu.class.getName())) {
return new ACpu();
} else if (classType.getName().equals(BCpu.class.getName())) {
return new BCpu();
}
return null;
}
} package com.taobao.migao.pattern.factory.simplefactory;
/**
* Test class – client code
*/
public class SimpleFactoryTest {
public static void main(String[] args) {
Cpu cpu = CpuFactory.createCpu(BCpu.class);
cpu.calculate();
}
}Factory Method Detailed
The factory itself is abstract; each concrete factory creates a specific product.
package com.taobao.migao.pattern.factory.factorymethod;
/**
* Product abstract interface: CPU
*/
public interface Cpu {
void calculate();
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Concrete product: A CPU
*/
public class ACpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is A cpu");
}
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Concrete product: B CPU
*/
public class BCpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is B cpu");
}
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Abstract factory for CPU
*/
public interface CpuFactory {
Cpu createCpu();
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Concrete factory for A CPU
*/
public class ACpuFactory implements CpuFactory {
@Override
public Cpu createCpu() {
return new ACpu();
}
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Concrete factory for B CPU
*/
public class BCpuFactory implements CpuFactory {
@Override
public Cpu createCpu() {
return new BCpu();
}
} package com.taobao.migao.pattern.factory.factorymethod;
/**
* Test class using concrete factories
*/
public class FactoryMethodTest {
public static void main(String[] args) {
CpuFactory factory = new ACpuFactory();
Cpu cpu = factory.createCpu();
cpu.calculate();
}
}Key Differences Between Simple Factory and Factory Method
Simple Factory: client passes a parameter; the factory decides which product to create.
Factory Method: each concrete factory is responsible for a single product; decision logic resides in the client.
Adding new products: Simple Factory requires modifying the factory; Factory Method only needs a new concrete factory.
Abstract Factory Detailed
Abstract factory creates families of related products (e.g., CPU, motherboard) together.
package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Abstract product: CPU
*/
public interface Cpu {
void calculate();
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Abstract product: Mainboard
*/
public interface Mainboard {
void installCpu();
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete CPU: A
*/
public class ACpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is A cpu");
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete CPU: B
*/
public class BCpu implements Cpu {
@Override
public void calculate() {
System.out.println("this is B cpu");
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete Mainboard: A
*/
public class AMainboard implements Mainboard {
@Override
public void installCpu() {
System.out.println("this is A mainboard");
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete Mainboard: B
*/
public class BMainboard implements Mainboard {
@Override
public void installCpu() {
System.out.println("this is B mainboard");
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Abstract factory interface
*/
public interface AbstractFactory {
Cpu createCpu();
Mainboard createMainboard();
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete factory for product family A
*/
public class AFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
return new ACpu();
}
@Override
public Mainboard createMainboard() {
return new AMainboard();
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Concrete factory for product family B
*/
public class BFactory implements AbstractFactory {
@Override
public Cpu createCpu() {
return new BCpu();
}
@Override
public Mainboard createMainboard() {
return new BMainboard();
}
} package com.taobao.migao.pattern.factory.abstractfactory;
/**
* Test class demonstrating context usage
*/
public class AbstractFactoryTest {
public static void main(String[] args) {
AbstractFactory factory = new AFactory();
Cpu cpu = factory.createCpu();
Mainboard mainboard = factory.createMainboard();
cpu.calculate();
mainboard.installCpu();
}
}Static Methods in Factory Patterns
In Simple Factory, the creation method can be static because there is no abstract factory interface. In Factory Method and Abstract Factory, the factory methods belong to interfaces and cannot be static (prior to Java 8). Since Java 8, interfaces may contain static methods with bodies, but the core pattern still relies on instance methods.
Understanding static in interfaces
Traditionally, interface methods are public abstract; they cannot be static. From Java 8 onward, static methods with implementations are allowed, but they are not part of the pattern’s contract.
When to Use Each Factory Pattern
Use Simple Factory for straightforward object creation without the need for extensibility.
Use Factory Method when you need to adhere to the Open‑Closed Principle and add new product types without modifying existing factories.
Use Abstract Factory when a system works with multiple related product families that must be created together.
Pros and Cons of Abstract Factory
Advantages
Decouples client code from concrete implementations.
Facilitates easy switching between product families.
Disadvantages
Adding a new product type requires changes to the abstract factory and all concrete factories.
Best Practices
Prefer Abstract Factory when dealing with multiple related products; use Simple Factory only for single‑product scenarios.
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.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
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.
