Skip to content

Enterprise Architecture ​

Scale specifications from single applications to enterprise ecosystems. Learn patterns that work across microservices, event-driven architectures, and complex distributed systems.

The Enterprise Challenge ​

At enterprise scale, you face:

  • Distributed systems across multiple services
  • Heterogeneous technologies and platforms
  • Complex governance requirements
  • Performance at scale with millions of transactions
  • Regulatory compliance across jurisdictions

Specifications solve these challenges elegantly.

Microservices and Specifications ​

Shared Specifications Across Services ​

php
// Shared Specification Library (composer package)
namespace Enterprise\SharedSpecifications;

class ComplianceSpecification extends AbstractSpecification
{
    public function __construct(
        private string $regulation,
        private string $jurisdiction
    ) {}
    
    public function isSatisfiedBy(mixed $transaction): bool
    {
        return match($this->regulation) {
            'GDPR' => $this->checkGDPR($transaction),
            'CCPA' => $this->checkCCPA($transaction),
            'SOX' => $this->checkSOX($transaction),
            'HIPAA' => $this->checkHIPAA($transaction),
            default => false
        };
    }
    
    public function toServiceContract(): array
    {
        return [
            'specification' => static::class,
            'regulation' => $this->regulation,
            'jurisdiction' => $this->jurisdiction,
            'version' => $this->getVersion(),
        ];
    }
}

Service Boundary Specifications ​

php
// Order Service
namespace Services\Order\Specifications;

class OrderServiceBoundarySpecification extends AbstractSpecification
{
    public function canProcessRequest(Request $request): bool
    {
        $validRequest = new ValidOrderRequestSpecification();
        $authorized = new AuthorizedOrderAccessSpecification();
        $withinScope = new WithinOrderServiceScopeSpecification();
        
        return $validRequest
            ->and($authorized)
            ->and($withinScope)
            ->isSatisfiedBy($request);
    }
}

// Customer Service
namespace Services\Customer\Specifications;

class CustomerServiceBoundarySpecification extends AbstractSpecification
{
    public function canProcessRequest(Request $request): bool
    {
        $validRequest = new ValidCustomerRequestSpecification();
        $authorized = new AuthorizedCustomerAccessSpecification();
        $withinScope = new WithinCustomerServiceScopeSpecification();
        
        return $validRequest
            ->and($authorized)
            ->and($withinScope)
            ->isSatisfiedBy($request);
    }
}

Cross-Service Specification Orchestration ​

php
class DistributedSpecificationOrchestrator
{
    private array $serviceEndpoints = [];
    
    public function evaluateAcrossServices(
        SpecificationInterface $spec,
        mixed $data
    ): array {
        $results = [];
        
        // Parallel evaluation across services
        $promises = [];
        foreach ($this->getRelevantServices($spec) as $service) {
            $promises[$service] = $this->evaluateOnService($service, $spec, $data);
        }
        
        // Collect results
        foreach ($promises as $service => $promise) {
            $results[$service] = $promise->wait();
        }
        
        return $this->aggregateResults($results);
    }
    
    private function evaluateOnService(
        string $service,
        SpecificationInterface $spec,
        mixed $data
    ): PromiseInterface {
        return Http::async()->post("{$service}/specifications/evaluate", [
            'specification' => $spec->toServiceContract(),
            'data' => $data,
        ]);
    }
}

Event-Driven Specifications ​

Event Sourcing with Specifications ​

php
class EventStore
{
    public function append(DomainEvent $event): void
    {
        // Validate event with specifications
        $validEventSpec = new ValidEventSpecification();
        
        if (!$validEventSpec->isSatisfiedBy($event)) {
            throw new InvalidEventException();
        }
        
        // Check business rules before storing
        $businessRulesSpec = $this->getBusinessRulesForEvent($event);
        
        if (!$businessRulesSpec->isSatisfiedBy($event)) {
            throw new BusinessRuleViolationException();
        }
        
        $this->store($event);
        $this->publish($event);
    }
    
    public function replay(SpecificationInterface $spec): Generator
    {
        // Replay only events matching specification
        foreach ($this->events as $event) {
            if ($spec->isSatisfiedBy($event)) {
                yield $event;
            }
        }
    }
}

Event-Driven Specifications ​

php
class EventDrivenSpecificationEngine
{
    private array $specifications = [];
    private array $handlers = [];
    
    public function register(
        SpecificationInterface $spec,
        callable $handler
    ): void {
        $this->specifications[] = $spec;
        $this->handlers[] = $handler;
    }
    
    public function process(DomainEvent $event): void
    {
        foreach ($this->specifications as $index => $spec) {
            if ($spec->isSatisfiedBy($event)) {
                $this->handlers[$index]($event);
            }
        }
    }
}

// Usage
$engine = new EventDrivenSpecificationEngine();

// Register specifications and handlers
$engine->register(
    new HighValueOrderPlacedSpecification(),
    fn($event) => dispatch(new NotifyAccountManager($event))
);

$engine->register(
    new FraudulentActivityDetectedSpecification(),
    fn($event) => dispatch(new BlockAccountImmediately($event))
);

$engine->register(
    new CustomerChurnRiskSpecification(),
    fn($event) => dispatch(new InitiateRetentionCampaign($event))
);

CQRS with Specifications ​

php
// Command Side
class CommandHandler
{
    public function handle(Command $command): void
    {
        // Validate command with specifications
        $validCommandSpec = new ValidCommandSpecification();
        
        if (!$validCommandSpec->isSatisfiedBy($command)) {
            throw new InvalidCommandException();
        }
        
        // Check business rules
        $businessRulesSpec = $this->getBusinessRulesForCommand($command);
        
        if (!$businessRulesSpec->isSatisfiedBy($command)) {
            throw new BusinessRuleViolationException(
                $businessRulesSpec->getViolations($command)
            );
        }
        
        // Execute command
        $aggregate = $this->repository->load($command->getAggregateId());
        $aggregate->handle($command);
        $this->repository->save($aggregate);
    }
}

// Query Side
class QueryHandler
{
    public function handle(Query $query): QueryResult
    {
        // Build specification from query
        $spec = $this->buildSpecificationFromQuery($query);
        
        // Apply to read model
        return $this->readModel
            ->whereSpecification($spec)
            ->with($query->getIncludes())
            ->paginate($query->getPerPage());
    }
    
    private function buildSpecificationFromQuery(Query $query): SpecificationInterface
    {
        $builder = new SpecificationBuilder();
        
        foreach ($query->getFilters() as $filter) {
            $builder->add($this->createSpecificationForFilter($filter));
        }
        
        return $builder->build();
    }
}

Enterprise Integration Patterns ​

Message Routing with Specifications ​

php
class SpecificationBasedRouter
{
    private array $routes = [];
    
    public function addRoute(
        SpecificationInterface $spec,
        string $destination
    ): void {
        $this->routes[] = [
            'specification' => $spec,
            'destination' => $destination,
        ];
    }
    
    public function route(Message $message): array
    {
        $destinations = [];
        
        foreach ($this->routes as $route) {
            if ($route['specification']->isSatisfiedBy($message)) {
                $destinations[] = $route['destination'];
            }
        }
        
        return $destinations;
    }
}

// Configure routing
$router = new SpecificationBasedRouter();

$router->addRoute(
    new HighPriorityMessageSpecification(),
    'priority-queue'
);

$router->addRoute(
    new CustomerServiceMessageSpecification(),
    'customer-service-queue'
);

$router->addRoute(
    new OrderProcessingMessageSpecification(),
    'order-processing-queue'
);

Content-Based Message Filtering ​

php
class MessageFilter
{
    public function filter(
        array $messages,
        SpecificationInterface $spec
    ): array {
        return array_filter(
            $messages,
            fn($message) => $spec->isSatisfiedBy($message)
        );
    }
    
    public function split(
        array $messages,
        array $specifications
    ): array {
        $buckets = [];
        
        foreach ($specifications as $key => $spec) {
            $buckets[$key] = $this->filter($messages, $spec);
        }
        
        return $buckets;
    }
}

Enterprise Service Bus (ESB) Integration ​

php
class SpecificationESBAdapter
{
    private ESBClient $esb;
    
    public function publishSpecification(
        SpecificationInterface $spec,
        string $topic
    ): void {
        $this->esb->publish($topic, [
            'type' => 'specification',
            'class' => get_class($spec),
            'definition' => $spec->toServiceContract(),
            'version' => $spec->getVersion(),
            'timestamp' => now(),
        ]);
    }
    
    public function subscribeToSpecifications(
        string $topic,
        callable $handler
    ): void {
        $this->esb->subscribe($topic, function($message) use ($handler) {
            if ($message['type'] === 'specification') {
                $spec = $this->hydrateSpecification($message);
                $handler($spec);
            }
        });
    }
    
    private function hydrateSpecification(array $message): SpecificationInterface
    {
        $class = $message['class'];
        return $class::fromServiceContract($message['definition']);
    }
}

API Gateway Specifications ​

php
class APIGatewaySpecificationMiddleware
{
    private array $routeSpecifications = [];
    
    public function handle(Request $request, Closure $next)
    {
        // Rate limiting specification
        $rateLimitSpec = new RateLimitSpecification(
            $request->user(),
            $request->route()
        );
        
        if (!$rateLimitSpec->isSatisfiedBy($request)) {
            return response()->json([
                'error' => 'Rate limit exceeded',
                'retry_after' => $rateLimitSpec->getRetryAfter(),
            ], 429);
        }
        
        // Authentication specification
        $authSpec = new AuthenticationSpecification();
        
        if (!$authSpec->isSatisfiedBy($request)) {
            return response()->json(['error' => 'Unauthorized'], 401);
        }
        
        // Authorization specification
        $authzSpec = new AuthorizationSpecification(
            $request->user(),
            $request->route()->getName()
        );
        
        if (!$authzSpec->isSatisfiedBy($request)) {
            return response()->json(['error' => 'Forbidden'], 403);
        }
        
        // Route to appropriate service
        $routingSpec = $this->getRoutingSpecification($request);
        $service = $this->determineService($routingSpec, $request);
        
        return $this->proxyToService($service, $request);
    }
}

Data Lake and Analytics ​

php
class DataLakeSpecificationEngine
{
    private DataLakeClient $dataLake;
    
    public function query(
        SpecificationInterface $spec,
        array $options = []
    ): DataLakeResult {
        // Convert specification to data lake query
        $query = $this->convertToDataLakeQuery($spec);
        
        // Apply optimizations
        $query = $this->optimizeQuery($query, $spec);
        
        // Execute with partitioning
        return $this->dataLake->query($query, [
            'partitions' => $this->determinePartitions($spec),
            'cache' => $options['cache'] ?? true,
            'timeout' => $options['timeout'] ?? 30000,
        ]);
    }
    
    private function convertToDataLakeQuery(
        SpecificationInterface $spec
    ): DataLakeQuery {
        $converter = new SpecificationToDataLakeConverter();
        return $converter->convert($spec);
    }
    
    private function determinePartitions(
        SpecificationInterface $spec
    ): array {
        // Analyze specification to determine optimal partitions
        $analyzer = new SpecificationPartitionAnalyzer();
        return $analyzer->analyze($spec);
    }
}

Enterprise Caching Strategy ​

php
class EnterpriseSpecificationCache
{
    private array $cacheLayers = [];
    
    public function __construct()
    {
        $this->cacheLayers = [
            'l1' => new InMemoryCache(),      // Application memory
            'l2' => new RedisCache(),          // Redis cluster
            'l3' => new ElasticsearchCache(),  // Elasticsearch
            'l4' => new CDNCache(),            // CDN edge cache
        ];
    }
    
    public function get(
        SpecificationInterface $spec,
        callable $resolver
    ): mixed {
        $key = $this->generateKey($spec);
        
        // Try each cache layer
        foreach ($this->cacheLayers as $layer => $cache) {
            if ($value = $cache->get($key)) {
                // Promote to higher layers
                $this->promoteToHigherLayers($layer, $key, $value);
                return $value;
            }
        }
        
        // Resolve and cache at all layers
        $value = $resolver();
        $this->cacheAtAllLayers($key, $value, $spec);
        
        return $value;
    }
    
    private function cacheAtAllLayers(
        string $key,
        mixed $value,
        SpecificationInterface $spec
    ): void {
        foreach ($this->cacheLayers as $cache) {
            $ttl = $this->determineTTL($spec, $cache);
            $cache->put($key, $value, $ttl);
        }
    }
}

Governance and Compliance ​

php
class SpecificationGovernanceEngine
{
    private array $policies = [];
    private AuditLogger $auditLogger;
    
    public function enforcePolicy(
        SpecificationInterface $spec,
        string $context
    ): ValidationResult {
        $result = new ValidationResult();
        
        // Check against governance policies
        foreach ($this->policies as $policy) {
            if (!$policy->allows($spec, $context)) {
                $result->addViolation($policy->getViolationMessage());
            }
        }
        
        // Audit the check
        $this->auditLogger->log([
            'specification' => get_class($spec),
            'context' => $context,
            'result' => $result->isValid() ? 'approved' : 'rejected',
            'violations' => $result->getViolations(),
            'timestamp' => now(),
            'user' => auth()->user()?->id,
        ]);
        
        return $result;
    }
}

Performance at Scale ​

Distributed Specification Evaluation ​

php
class DistributedSpecificationEvaluator
{
    private array $workers = [];
    
    public function evaluateInParallel(
        SpecificationInterface $spec,
        Collection $largeDataset
    ): Collection {
        // Chunk data for parallel processing
        $chunks = $largeDataset->chunk(1000);
        
        // Distribute to workers
        $promises = [];
        foreach ($chunks as $index => $chunk) {
            $worker = $this->selectWorker($index);
            $promises[] = $this->evaluateOnWorker($worker, $spec, $chunk);
        }
        
        // Collect results
        $results = collect();
        foreach ($promises as $promise) {
            $results = $results->merge($promise->wait());
        }
        
        return $results;
    }
    
    private function selectWorker(int $index): string
    {
        // Load balancing logic
        return $this->workers[$index % count($this->workers)];
    }
}

Specification Query Optimization ​

php
class SpecificationQueryOptimizer
{
    public function optimize(
        SpecificationInterface $spec
    ): OptimizedSpecification {
        // Analyze specification structure
        $analysis = $this->analyze($spec);
        
        // Apply optimization strategies
        $optimized = $this->applyOptimizations($spec, $analysis);
        
        // Generate execution plan
        $plan = $this->generateExecutionPlan($optimized);
        
        return new OptimizedSpecification($optimized, $plan);
    }
    
    private function applyOptimizations(
        SpecificationInterface $spec,
        array $analysis
    ): SpecificationInterface {
        $optimizations = [
            new PredicatePushdownOptimization(),
            new IndexUtilizationOptimization(),
            new PartitionPruningOptimization(),
            new MaterializedViewOptimization(),
            new CachingOptimization(),
        ];
        
        foreach ($optimizations as $optimization) {
            if ($optimization->canApply($spec, $analysis)) {
                $spec = $optimization->apply($spec);
            }
        }
        
        return $spec;
    }
}

Enterprise Monitoring ​

php
class SpecificationMonitor
{
    private MetricsCollector $metrics;
    
    public function monitor(
        SpecificationInterface $spec,
        callable $execution
    ): mixed {
        $startTime = microtime(true);
        $startMemory = memory_get_usage();
        
        try {
            $result = $execution();
            
            $this->metrics->record([
                'specification' => get_class($spec),
                'duration' => microtime(true) - $startTime,
                'memory' => memory_get_usage() - $startMemory,
                'status' => 'success',
                'timestamp' => now(),
            ]);
            
            return $result;
            
        } catch (\Exception $e) {
            $this->metrics->record([
                'specification' => get_class($spec),
                'duration' => microtime(true) - $startTime,
                'memory' => memory_get_usage() - $startMemory,
                'status' => 'failure',
                'error' => $e->getMessage(),
                'timestamp' => now(),
            ]);
            
            throw $e;
        }
    }
}

Enterprise Best Practices ​

1. Specification Versioning ​

php
interface VersionedSpecification extends SpecificationInterface
{
    public function getVersion(): string;
    public function isCompatibleWith(string $version): bool;
    public function migrate(mixed $data, string $fromVersion): mixed;
}

2. Specification Registry ​

php
class EnterpriseSpecificationRegistry
{
    private array $specifications = [];
    
    public function register(
        string $name,
        SpecificationInterface $spec,
        array $metadata = []
    ): void {
        $this->specifications[$name] = [
            'specification' => $spec,
            'metadata' => $metadata,
            'registered_at' => now(),
        ];
    }
    
    public function discover(): array
    {
        // Auto-discover specifications across services
        return $this->specifications;
    }
}

3. Specification Documentation ​

php
interface DocumentedSpecification extends SpecificationInterface
{
    public function getDescription(): string;
    public function getExamples(): array;
    public function getBusinessContext(): string;
    public function getPerformanceCharacteristics(): array;
}

The Enterprise Advantage ​

With enterprise specifications, you achieve:

  • Consistency across all services
  • Governance through specification policies
  • Scalability with distributed evaluation
  • Compliance with audit trails
  • Performance through optimization
  • Reliability with monitoring

Enterprise Scale

Specifications at enterprise scale aren't just patternsβ€”they're the foundation for consistent, governable, scalable business logic across your entire organization.

Ready for Advanced Patterns? ​

Explore cutting-edge specification patterns that push the boundaries of what's possible.

Discover Advanced Patterns β†’

References ​

  1. Fowler, Martin (2002). Patterns of Enterprise Application Architecture. Addison-Wesley Professional. ISBN 0-321-12742-0.

  2. Richardson, Chris (2018). Microservices Patterns. Manning Publications. ISBN 1-617-29482-9.

  3. Newman, Sam (2015). Building Microservices. O'Reilly Media. ISBN 1-491-95035-7.

  4. Kleppmann, Martin (2017). Designing Data-Intensive Applications. O'Reilly Media. ISBN 1-449-37332-0.

  5. Vernon, Vaughn (2013). Implementing Domain-Driven Design. Addison-Wesley Professional. ISBN 0-321-83457-4.

  6. Young, Greg (2010). "CQRS Documents". Available online: cqrs.files.wordpress.com

  7. Helland, Pat & Campbell, Dave (2009). "Building on Quicksand". CIDR Conference Proceedings.

  8. Hohpe, Gregor & Woolf, Bobby (2003). Enterprise Integration Patterns. Addison-Wesley Professional. ISBN 0-321-20068-3.

  9. Bass, Len et al. (2012). Software Architecture in Practice. 3rd ed. Addison-Wesley Professional. ISBN 0-321-81573-4.

  10. Tanenbaum, Andrew S. & Van Steen, Maarten (2016). Distributed Systems: Principles and Paradigms. 3rd ed. Pearson. ISBN 0-13-405952-0.

Released under the MIT License.