Package Boundary Patterns

Introduction

Defining clear package boundaries is crucial for maintainable, scalable Salesforce solutions. This document presents patterns for establishing and maintaining package boundaries based on production implementations managing 40+ packages.

Boundary Definition Strategies

1. Domain-Driven Boundaries

Packages align with business domains, containing all layers for that domain.

package-structure/
├── customer-management/
│   ├── domain/          # Customer, Contact domain logic
│   ├── services/        # Customer-specific services
│   ├── selectors/       # Customer data access
│   └── ui/             # Customer-specific UI
├── order-management/
│   ├── domain/          # Order, OrderItem logic
│   ├── services/        # Order processing
│   ├── selectors/       # Order data access
│   └── ui/             # Order UI components
└── inventory/
    ├── domain/          # Product, Stock logic
    ├── services/        # Inventory services
    ├── selectors/       # Inventory queries
    └── ui/             # Inventory UI

When to Use:

  • Clear business domain separation

  • Different teams own different domains

  • Domains have different change frequencies

2. Layer-Based Boundaries

Packages organized by architectural layers, cutting across domains.

When to Use:

  • High reuse across domains

  • Consistent technical patterns

  • Small team maintaining all domains

3. Capability-Based Boundaries

Packages provide specific capabilities independent of domain.

When to Use:

  • Cross-cutting concerns

  • Reusable across multiple orgs

  • Third-party integrations

Boundary Enforcement Patterns

1. Interface Segregation Pattern

Each package exposes minimal, focused interfaces.

2. Dependency Injection Pattern

Packages declare dependencies explicitly through constructor injection or property injection.

3. Package Registry Pattern

Central registry for package capabilities and services.

Cross-Package Communication Patterns

1. Service Mesh Pattern

Packages communicate through a service mesh layer that handles routing, security, and monitoring.

2. Event-Driven Communication

Packages communicate through Platform Events for loose coupling.

3. Configuration-Driven Routing

Use Custom Metadata to configure package interactions.

Package Versioning and Compatibility

1. Semantic Versioning Pattern

2. Backward Compatibility Pattern

Testing Package Boundaries

1. Contract Testing

2. Boundary Testing

Package Boundary Checklist

Design Phase

Implementation Phase

Testing Phase

Deployment Phase

Common Boundary Violations

1. Database Coupling

2. Shared Global Variables

3. Trigger Dependencies

Conclusion

Clear package boundaries are essential for:

  • Maintainability: Changes isolated to packages

  • Scalability: Add packages without affecting others

  • Testability: Test packages in isolation

  • Deployability: Deploy packages independently

  • Team Autonomy: Teams own clear boundaries

The key is finding the right balance between isolation and practicality for your specific context.

Last updated

Was this helpful?