MTI TEK
  • Home
  • About
  • LLMs
  • Docker
  • Kubernetes
  • Java
  • All Resources
Java Design Patterns | Abstract Factory
  1. Overview and Definition
  2. Class Diagram
  3. Implementation Example
    • The Abstract Products
    • The Concrete Products
    • The Abstract Factory
    • The Concrete Factories
    • The Factory Method Helper (Optional)
    • Testing the Abstract Factory Pattern

  1. Overview and Definition
    The Abstract Factory pattern is a creational design pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. Unlike the Factory Method pattern which creates single objects, the Abstract Factory creates entire product families that work together.

    Key Components:
    • Abstract Product: Interfaces or abstract classes that define the common interface for each product type in the family.
    • Concrete Product: Specific implementations of Abstract Products that belong to the same product family.
    • Abstract Factory: An interface that declares methods for creating each type of abstract product.
    • Concrete Factory: Classes that implement the Abstract Factory interface and create concrete products that belong to the same family.
    • Client: The code that uses the Abstract Factory and Abstract Products without knowing the specific implementations.

    Benefits:
    • Loose Coupling: Client code depends only on abstract interfaces, not concrete implementations.
    • Extensibility: New product families can be added by creating new concrete factories and products without modifying existing code.
  2. Class Diagram
    Abstract Factory Pattern Components:
    • Abstract Products: Table and Column interfaces - define the common interface for each product type.
    • Concrete Products: OracleTable, DerbyTable, OracleColumn, DerbyColumn - specific implementations that belong to the same family.
    • Abstract Factory: SchemaFactory interface - declares methods for creating each type of abstract product.
    • Concrete Factories: OracleSchemaFactory, DerbySchemaFactory - create concrete products that work together as a family.
    ┌────────────────────────────┐      ┌────────────────────────────┐
    │       <<interface>>        │      │       <<interface>>        │
    │          Table             │      │          Column            │  ← Abstract Products
    ├────────────────────────────┤      ├────────────────────────────┤
    │ + toSQL(): String          │      │ + toSQL(): String          │
    └────────────────────────────┘      └────────────────────────────┘
                △                                   △
                │ implements                         │ implements
                │                                    │
    ┌─────────────────┬─────────────────┐           ┌──────────────────┬──────────────────┐
    │   OracleTable   │   DerbyTable    │           │  OracleColumn    │  DerbyColumn     │  ← Concrete Products
    ├─────────────────┼─────────────────┤           ├──────────────────┼──────────────────┤
    │+ toSQL(): String│+ toSQL(): String│           │+ toSQL(): String │+ toSQL(): String │
    └─────────────────┴─────────────────┘           └──────────────────┴──────────────────┘
    
    
    ┌────────────────────────────────────────────┐
    │               <<interface>>                │
    │               SchemaFactory                │  ← Abstract Factory
    ├────────────────────────────────────────────┤
    │ + createTable(): Table                     │
    │ + createColumn(): Column                   │
    └────────────────────────────────────────────┘
                      △
                      │ implements
                      │
    ┌─────────────────────────┬─────────────────────────┐
    │   OracleSchemaFactory   │   DerbySchemaFactory    │  ← Concrete Factories
    ├─────────────────────────┼─────────────────────────┤
    │+ createTable()          │+ createTable()          │
    │+ createColumn()         │+ createColumn()         │
    └─────────────────────────┴─────────────────────────┘
    
  3. Implementation Example
    • The Abstract Products:
      Abstract Products define the interfaces for different types of objects that the factory will create. In this database schema example, we have two product types: Table and Column.
      • Product A - Table:
        public interface Table {
            public String toSQL();
        }
      • Product B - Column:
        public interface Column {
            public String toSQL();
        }
    • The Concrete Products:
      Concrete Products implement the Abstract Product interfaces and provide specific functionality. Products from the same family (Oracle or Derby) are designed to work together.
      • Table Implementations:
        • Oracle Database:
          public class OracleTable implements Table {
              public String toSQL() {
                  return "OracleTable - toSQL";
              }
          }
        • Derby Database:
          public class DerbyTable implements Table {
              public String toSQL() {
                  return "DerbyTable - toSQL";
              }
          }
      • Column Implementations:
        • Oracle Database:
          public class OracleColumn implements Column {
              public String toSQL() {
                  return "OracleColumn - toSQL";
              }
          }
        • Derby Database:
          public class DerbyColumn implements Column {
              public String toSQL() {
                  return "DerbyColumn - toSQL";
              }
          }
    • The Abstract Factory:
      The Abstract Factory interface declares creation methods for each type of abstract product. This ensures that concrete factories create complete families of related objects.
      public interface SchemaFactory {
          public Table createTable();
      
          public Column createColumn();
      }
    • The Concrete Factories:
      Concrete Factories implement the Abstract Factory interface and create products that belong to the same family. Each factory ensures that all created objects are compatible with each other.
      • Oracle SchemaFactory Factory:
        public class OracleSchemaFactory implements SchemaFactory {
            public Table createTable() {
                return new OracleTable();
            }
        
            public Column createColumn() {
                return new OracleColumn();
            }
        }
      • Derby SchemaFactory Factory:
        public class DerbySchemaFactory implements SchemaFactory {
            public Table createTable() {
                return new DerbyTable();
            }
        
            public Column createColumn() {
                return new DerbyColumn();
            }
        }
    • The Factory Method Helper (Optional):
      This helper class uses the Factory Method pattern to create the appropriate Abstract Factory instance based on input parameters. This adds an extra layer of abstraction for factory selection.
      public class FactoryMethodSchema {
          public static SchemaFactory getSchema(final String type) {
              if ("oracle".equalsIgnoreCase(type)) {
                  return new OracleSchemaFactory();
              } else if ("derby".equalsIgnoreCase(type)) {
                  return new DerbySchemaFactory();
              }
      
              return null;
          }
      }
    • Testing the Abstract Factory Pattern:
      The client code demonstrates how to use the Abstract Factory to create families of related objects.
      public class AbstractFactoryPatternTest {
          public static void main(String[] args) {
              // Example 1: Oracle Database
              
              // Get the Oracle factory using the factory method helper
              final SchemaFactory oracleSchema = FactoryMethodSchema.getSchema("oracle");
      
              // Create Oracle-specific products using the factory
              final Table oracleTable = oracleSchema.createTable();
              final Column oracleColumn = oracleSchema.createColumn();
      
              // Use the Oracle products (both belong to the same family)
              final String s_oracleTable = oracleTable.toSQL();
              final String s_oracleColumn = oracleColumn.toSQL();
              System.out.println("Oracle Database: " + s_oracleTable + " / " + s_oracleColumn);
      
              // Example 2: Derby Database
              
              // Get the Derby factory using the factory method helper
              final SchemaFactory derbySchema = FactoryMethodSchema.getSchema("derby");
      
              // Create Derby-specific products using the factory
              final Table derbyTable = derbySchema.createTable();
              final Column derbyColumn = derbySchema.createColumn();
      
              // Use the Derby products (both belong to the same family)
              final String s_derbyTable = derbyTable.toSQL();
              final String s_derbyColumn = derbyColumn.toSQL();
              System.out.println("Derby Database: " + s_derbyTable + " / " + s_derbyColumn);
          }
      }
© 2025 mtitek