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 UIWhen 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?