Destination
Design Pattern – Abstract factory is one of the design patterns. It provides an interface, which is responsible for creation related objects without specifying their class.
When to use Abstract Factory?
- When the system should be independent of the creation method, construction and object representation
- If it is possible to divide products to the product family
- Products are designed to common use
- If a developer wants to provide only an interface, without the implementation
Implementation of Abstract Factory
/* Country Interface */
public interface Country {
void payTax();
}
/* Poland */
public class Poland implements Country {
public void payTax() {
System.debug('payTax VAT 23%');
}
}
/* Luxembourg */
public class Luxembourg implements Country {
public void payTax() {
System.debug('payTax VAT 17%');
}
}
/* USA */
public class USA implements Country {
public void payTax() {
System.debug('payTax VAT 15%');
}
}
/* CountriesAbstractFactory */
public abstract class CountriesAbstractFactory {
public abstract Country getCountry(Countries countryName);
}
/* Countries */
public enum Countries {
POLAND,
LUXEMBOURG,
USA
}
/* EuropeCountriesFactory */
public class EuropeCountriesFactory extends CountriesAbstractFactory {
private FINAL Map<Countries, Country> countryName2Object = new Map<Countries, Country> {
Countries.POLAND => new Poland(),
Countries.LUXEMBOURG => new Luxembourg ()
};
public override Country getCountry(Countries countryName) {
return this.countryName2Object.get(countryName);
}
}
/* NorthAmericaCountriesFactory */
public class NorthAmericaCountriesFactory extends CountriesAbstractFactory {
private FINAL Map<Countries, Country> countryName2Object = new Map<Countries, Country> {
Countries.USA => new USA()
};
public override Country getCountry(Countries countryName) {
return this.countryName2Object.get(countryName);
}
}
/* Continents */
public enum Continents {
EUROPE,
NORTH_AMERICA
}
/* CountryFactory */
public class CountryFactory {
public static CountriesAbstractFactory getCountries(Continents continent) {
if (continent == Continents.EUROPE) {
return new EuropeCountriesFactory();
} else if (continent == Continents.NORTH_AMERICA) {
return new NorthAmericaCountriesFactory();
} else {
return null;
}
}
}
/* Example of invoke */
CountriesAbstractFactory europeCountries = CountryFactory.getCountries(Continents.EUROPE);
Country poland = europeCountries.getCountry(Countries.POLAND);
poland.payTax();
Country luxembourg = europeCountries.getCountry(Countries.LUXEMBOURG);
luxembourg.payTax();
CountriesAbstractFactory northAmericaCountries = CountryFactory.getCountries(Continents.NORTH_AMERICA);
Country usa = northAmericaCountries.getCountry(Countries.USA);
usa.payTax();
Diagram

Resources
- https://readsalesforce.wordpress.com/2018/06/18/abstract-classes-understanding-in-apex-salesforce-com/
- https://refactoring.guru/design-patterns/abstract-factory
- https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm
- https://developer.salesforce.com/page/Apex_Design_Patterns
Was it helpful? Check out our other great articles here.