Simple Factory Pattern Implementation in Object-Oriented Programming

The simple factory pattern represents a fundamental design approach that simplifies object creation processes. While not always included in traditional design pattern catalogs, this pattern provides significant value in code organization and maintainability.

Traditional Approach Without Patterns

Consider a basic object-oriented implementation where direct instantiation occurs:

/****************** Interface Definition ********************/
public interface DataProcessor {
    void executeProcessing(String inputData);
}

/****************** Concrete Implementation *****************/

class DatabaseProcessor implements DataProcessor {
    
    @Override
    public void executeProcessing(String inputData) {
        System.out.println("Processing through database: " + inputData);
    }
    
}

/****************** Direct Client Usage **********************/
public class ApplicationClient {

    public static void main(String[] args) {
        DataProcessor processor = new DatabaseProcessor();
        processor.executeProcessing("Sample data for processing");
    }
}

This direct approach works well for simple applications but creates tight coupling between clients and specific implementations. The client must know about concrete classes, which violates encapsulation principles and makes the system harder to maintain.

Introducing the Factory Solution

To address these issues, we introduce a factory class that handles object creation:

/**
 * Centralized factory for creating processor instances
 */
public class ProcessorFactory {
    
    public static DataProcessor generateProcessor() {
        return new DatabaseProcessor();
    }
}

With this factory in place, client code becomes more flexible:

public class ApplicationClient {

    public static void main(String[] args) {
        // Old approach: tight coupling
        // DataProcessor processor = new DatabaseProcessor();
        
        // New approach: using factory
        DataProcessor processor = ProcessorFactory.generateProcessor();
        processor.executeProcessing("Created via factory pattern");
    }
}

The client now depends only on the interface and factory, not specific implementations. This decouples the client from concrete classes.

Enhanced Factory with Multiple Types

Real-world scenarios often require multiple implementations based on different criteria:

/**
 * Advanced factory supporting multiple processor types
 */
public class AdvancedProcessorFactory {
    
    public static final String DATABASE_TYPE = "db";
    public static final String FILE_TYPE = "file";
    public static final String API_TYPE = "api";
    
    public static DataProcessor generateProcessor(String processorType) {
        DataProcessor processor = null;
        
        switch (processorType.toLowerCase()) {
            case DATABASE_TYPE:
                processor = new DatabaseProcessor();
                break;
            case FILE_TYPE:
                processor = new FileProcessor();
                break;
            case API_TYPE:
                processor = new ApiProcessor();
                break;
        }
        
        return processor;
    }
}

// Example usage
public class ApplicationClient {
    public static void main(String[] args) {
        // Create database processor
        DataProcessor dbProcessor = AdvancedProcessorFactory.generateProcessor(
            AdvancedProcessorFactory.DATABASE_TYPE);
        dbProcessor.executeProcessing("Database operation");
        
        // Create file processor
        DataProcessor fileProcessor = AdvancedProcessorFactory.generateProcessor(
            AdvancedProcessorFactory.FILE_TYPE);
        fileProcessor.executeProcessing("File operation");
    }
}

Configuration-Based Approach

To maximum flexibility, factories can read configuration files to determine wich implementations to instantiate. This allows runtime selection of implementations without code changes.

Pattern Analysis

Definition: The simple factory pattern provides a centralized mechanism for creating objects without exposing the instantiation logic to clients.

Benefits:

  • Improved encapsulation through hidden implementation details
  • Decoupling between clients and concrete implementations
  • Centralized management of object creation logic
  • Easier maintenance and extension capabilities

Drawbacks:

  • Increased code complexity due to additional factory classes
  • Potential violation of open-closed principle when adding new types

Use Cases:

  • Applications requiring multiple implementations of the same interface
  • Systems where object creation logic needs centralization
  • Scenarios involving complex initialization procedures

The simple factory pattern serves as a foundational building block for more sophisticated factory patterns and remains widely used in enterprise applications.

Tags: design-patterns factory-pattern object-oriented-programming software-architecture java

Posted on Fri, 31 Jul 2026 16:23:39 +0000 by RonDahl