Factory Pattern
By the end of this lesson, you'll be able to:
- Define the factory pattern and the problem it solves
- Write a factory that constructs the correct concrete class based on a runtime condition
- Distinguish a factory from simple dependency injection
Prerequisites: "Dependency Injection in Apex"
A scenario factory alone doesn't cover
Suppose the banking system needs different overdraft rules for Personal versus Business accounts — a Business account might be allowed a modest negative balance, while a Personal account never is. Lesson 6's dependency injection helps swap a dependency for a test, but doesn't answer: at runtime, in production, how does the code decide which validation rule applies to a given transaction?
The factory decides, based on data
public interface IOverdraftPolicy {
Boolean allows(Decimal balance, Decimal withdrawalAmount);
}
public class PersonalOverdraftPolicy implements IOverdraftPolicy {
public Boolean allows(Decimal balance, Decimal withdrawalAmount) {
return withdrawalAmount <= balance;
}
}
public class BusinessOverdraftPolicy implements IOverdraftPolicy {
private static final Decimal OVERDRAFT_LIMIT = 500;
public Boolean allows(Decimal balance, Decimal withdrawalAmount) {
return withdrawalAmount <= balance + OVERDRAFT_LIMIT;
}
}
public class OverdraftPolicyFactory {
public static IOverdraftPolicy getPolicyFor(String accountType) {
if (accountType == 'Business') return new BusinessOverdraftPolicy();
return new PersonalOverdraftPolicy();
}
}
OverdraftPolicyFactory.getPolicyFor is the single place this runtime decision is made — calling code doesn't need an if/else on account type at all, it just asks the factory for the right policy and calls allows().
Factory versus plain dependency injection
Lesson 6's dependency injection is about how a dependency reaches a class (from outside, via constructor). The factory pattern is about which concrete implementation gets chosen in the first place, based on runtime data — the two patterns work well together: TransactionValidationService could accept an IOverdraftPolicy via its constructor (dependency injection), while OverdraftPolicyFactory decides which one to inject (the factory pattern), keeping each concern separate.
Exercise
As a comment, explain why calling code that needs an overdraft policy should call OverdraftPolicyFactory.getPolicyFor rather than writing its own if (accountType == 'Business') check directly.
Show hint
Think about what happens if a third account type is added later.
Factory Pattern Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
A factory centralizes the decision of *which* concrete class to construct, when that decision depends on runtime conditions rather than being fixed at compile time — useful when a system needs different behavior for different account types, regions, or configurations.