Design Patterns #2 – Abstract Factory

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

diagram of abstract factory design pattern

Resources

Was it helpful? Check out our other great articles here.

5 2 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
Close Menu
0
Would love your thoughts, please comment.x
()
x