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 β
// 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 β
// 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 β
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 β
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 β
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 β
// 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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
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 β
Fowler, Martin (2002). Patterns of Enterprise Application Architecture. Addison-Wesley Professional. ISBN 0-321-12742-0.
Richardson, Chris (2018). Microservices Patterns. Manning Publications. ISBN 1-617-29482-9.
Newman, Sam (2015). Building Microservices. O'Reilly Media. ISBN 1-491-95035-7.
Kleppmann, Martin (2017). Designing Data-Intensive Applications. O'Reilly Media. ISBN 1-449-37332-0.
Vernon, Vaughn (2013). Implementing Domain-Driven Design. Addison-Wesley Professional. ISBN 0-321-83457-4.
Young, Greg (2010). "CQRS Documents". Available online: cqrs.files.wordpress.com
Helland, Pat & Campbell, Dave (2009). "Building on Quicksand". CIDR Conference Proceedings.
Hohpe, Gregor & Woolf, Bobby (2003). Enterprise Integration Patterns. Addison-Wesley Professional. ISBN 0-321-20068-3.
Bass, Len et al. (2012). Software Architecture in Practice. 3rd ed. Addison-Wesley Professional. ISBN 0-321-81573-4.
Tanenbaum, Andrew S. & Van Steen, Maarten (2016). Distributed Systems: Principles and Paradigms. 3rd ed. Pearson. ISBN 0-13-405952-0.