Class Folder Organization Patterns

Introduction

Salesforce's default structure puts all Apex classes in a single classes folder, which becomes unmanageable at scale. This document presents patterns for organizing classes into logical subfolders, based on production implementations with hundreds of classes per package.

Why Folder Organization Matters

The Problem with Flat Structure

// ❌ Default Salesforce structure with 200+ files
classes/
├── AccountService.cls
├── AccountServiceImpl.cls
├── AccountServiceTest.cls
├── AccountSelector.cls
├── AccountSelectorTest.cls
├── AccountDomain.cls
├── AccountDomainTest.cls
├── AccountTriggerHandler.cls
├── AccountFactory.cls
├── IAccountService.cls
├── IAccountSelector.cls
├── OrderService.cls
├── OrderServiceImpl.cls
├── OrderServiceTest.cls
... (185 more files)

Problems:

  • Impossible to find related classes

  • No clear architecture visible

  • Merge conflicts on every PR

  • IDE performance issues

  • New developers lost

Folder Organization Patterns

1. Layer-Based Organization (fflib Pattern)

Organize by architectural layer following enterprise patterns:

2. Test Organization Pattern

Tests mirror the source structure in a separate test folder:

3. Sub-Package Organization

For sub-packages within a larger package (modular within modular):

4. Interface Segregation Pattern

Interfaces in dedicated subfolders for clear contracts:

Package-Specific Application Classes

The Multi-Application Pattern

In modular architectures, each package has its own Application_{XX} class with package-specific suffix:

Why Multiple Selectors for Same Object?

Each package needs different fields from the same object:

Package Suffix Convention

Use consistent 2-3 letter suffixes across all layers:

Selector Factory Pattern

Each package-specific selector implements the factory pattern:

Using Package-Specific Components

Services use the appropriate Application class:

Naming Conventions

Folder Names

  • Lowercase: services, domains, selectors

  • Plural for collections: controllers, factories

  • Descriptive: implementations not impl

Class Names

  • Services: {Entity}Service + I{Entity}Service interface

  • Selectors: {Entity}sSelector + I{Entity}sSelector interface

  • Domains: {Entity}s (plural) + I{Entity}s interface

  • Controllers: {Feature}Controller

  • Tests: {ClassName}Test

File Placement Rules

Benefits of Folder Organization

1. Improved Developer Experience

  • Find files faster: Related classes grouped together

  • Understand architecture: Structure visible in folder layout

  • Reduce cognitive load: Clear separation of concerns

2. Better Code Quality

  • Enforce architecture: Folder structure enforces patterns

  • Reduce coupling: Clear boundaries between layers

  • Easier reviews: Reviewers know where to look

3. Team Scalability

  • Parallel development: Teams work in different folders

  • Clear ownership: Folders can have code owners

  • Onboarding: New developers understand structure

4. Maintenance Benefits

  • Easier refactoring: Related code in one place

  • Dependency tracking: Clear layer dependencies

  • Test organization: Tests mirror source structure

Anti-Patterns to Avoid

1. Over-Nesting

2. Inconsistent Organization

3. Breaking Salesforce Conventions

Migration Strategy

Phase 1: Plan Structure

  1. Audit existing classes

  2. Map to target folders

  3. Identify dependencies

  4. Create folder structure

Phase 2: Gradual Migration

Phase 3: Update References

Production Implementation Results

Effective folder organization in production systems shows:

Why this works:

  • Predictable navigation: Developers know exactly where to find code

  • Clear architecture: Folder structure enforces architectural patterns

  • Reduced conflicts: Teams work in separate folders without collision

  • Scalable growth: Structure maintains clarity as the codebase grows

  • Test organization: Tests automatically follow the same structure

Conclusion

Organizing classes into folders is essential for:

  • Maintainability at scale

  • Architectural clarity

  • Team productivity

  • Code quality

The key is choosing a consistent pattern that fits your architecture and sticking to it across all packages.

Last updated

Was this helpful?