bc-code-intelligence-mcp
Version:
BC Code Intelligence MCP Server - Complete Specialist Bundle with AI-driven expert consultation, seamless handoffs, and context-preserving workflows
325 lines (263 loc) • 10.1 kB
Markdown
# Complex Facade Patterns Sample
## Overview
This sample demonstrates advanced facade pattern implementations for enterprise scenarios including multi-layer facades, composition patterns, and complex system integration.
## Multi-Layer Facade Architecture
```al
// Business Service Layer Facade
codeunit 50200 "Sales Order Service Facade"
{
var
DocumentFacade: Codeunit "Document Processing Facade";
ValidationFacade: Codeunit "Sales Validation Facade";
IntegrationFacade: Codeunit "External Integration Facade";
procedure ProcessSalesOrder(var SalesHeader: Record "Sales Header"): Boolean
begin
if not ValidationFacade.ValidateOrder(SalesHeader) then
exit(false);
if not DocumentFacade.ProcessDocument(SalesHeader) then
exit(false);
if SalesHeader."External Integration Required" then
IntegrationFacade.NotifyExternalSystems(SalesHeader);
exit(true);
end;
procedure CreateCompleteOrder(CustomerNo: Code[20]; Items: List of [Text]): Code[20]
var
SalesHeader: Record "Sales Header";
OrderBuilder: Codeunit "Sales Order Builder";
begin
// Composite operation using multiple facades
SalesHeader := OrderBuilder.CreateHeader(CustomerNo);
OrderBuilder.AddItems(SalesHeader, Items);
ValidationFacade.ValidateCompleteOrder(SalesHeader);
DocumentFacade.FinalizeDocument(SalesHeader);
exit(SalesHeader."No.");
end;
}
```
## Facade Composition Pattern
```al
// Document Processing Facade (Lower Level)
codeunit 50201 "Document Processing Facade"
{
var
NumberSeriesMgmt: Codeunit "Number Series Management";
DocumentValidation: Codeunit "Document Validation";
StatusMgmt: Codeunit "Document Status Management";
procedure ProcessDocument(var SalesHeader: Record "Sales Header"): Boolean
var
ProcessingContext: Record "Document Processing Context";
begin
ProcessingContext := CreateProcessingContext(SalesHeader);
if not ValidateDocumentStructure(SalesHeader) then
exit(false);
AssignDocumentNumbers(SalesHeader);
UpdateDocumentStatus(SalesHeader, ProcessingContext);
LogProcessingActivity(SalesHeader, ProcessingContext);
exit(true);
end;
local procedure CreateProcessingContext(SalesHeader: Record "Sales Header"): Record "Document Processing Context"
var
Context: Record "Document Processing Context";
begin
Context."Document Type" := SalesHeader."Document Type";
Context."Document No." := SalesHeader."No.";
Context."Processing Started" := CurrentDateTime;
Context."User ID" := UserId;
Context.Insert();
exit(Context);
end;
}
```
## Context-Aware Facade
```al
codeunit 50202 "Context Aware Sales Facade"
{
procedure ProcessOrderByContext(var SalesHeader: Record "Sales Header"; Context: Enum "Processing Context"): Boolean
var
Strategy: Interface "Processing Strategy";
begin
Strategy := GetProcessingStrategy(Context);
exit(Strategy.ProcessOrder(SalesHeader));
end;
local procedure GetProcessingStrategy(Context: Enum "Processing Context"): Interface "Processing Strategy"
var
StandardStrategy: Codeunit "Standard Processing Strategy";
ExpressStrategy: Codeunit "Express Processing Strategy";
BulkStrategy: Codeunit "Bulk Processing Strategy";
begin
case Context of
Context::Standard:
exit(StandardStrategy);
Context::Express:
exit(ExpressStrategy);
Context::Bulk:
exit(BulkStrategy);
end;
end;
}
```
## Enterprise Integration Facade
```al
codeunit 50203 "Enterprise Integration Facade"
{
var
ERPConnector: Codeunit "ERP System Connector";
CRMConnector: Codeunit "CRM System Connector";
EDIProcessor: Codeunit "EDI Message Processor";
procedure SynchronizeCustomer(CustomerNo: Code[20]): Boolean
var
Customer: Record Customer;
SyncResult: Record "Integration Sync Result";
begin
if not Customer.Get(CustomerNo) then
exit(false);
// Coordinate multiple system integrations
SyncResult := InitializeSyncResult(CustomerNo);
if Customer."CRM Integration Enabled" then
UpdateCRMSyncResult(SyncResult, CRMConnector.SyncCustomer(Customer));
if Customer."ERP Integration Enabled" then
UpdateERPSyncResult(SyncResult, ERPConnector.SyncCustomer(Customer));
if Customer."EDI Integration Enabled" then
UpdateEDISyncResult(SyncResult, EDIProcessor.ProcessCustomerUpdate(Customer));
exit(SyncResult."Overall Success");
end;
procedure ProcessBulkIntegration(var Customers: Record Customer): Integer
var
SuccessCount: Integer;
Customer: Record Customer;
begin
Customers.FindSet();
repeat
if SynchronizeCustomer(Customers."No.") then
SuccessCount += 1;
until Customers.Next() = 0;
exit(SuccessCount);
end;
}
```
## Configurable Facade Pattern
```al
codeunit 50204 "Configurable Business Facade"
{
var
FacadeConfig: Record "Facade Configuration";
procedure ProcessBusinessTransaction(TransactionType: Enum "Business Transaction Type"; DataVariant: Variant): Boolean
var
ProcessingSteps: List of [Text];
StepName: Text;
begin
LoadConfiguration(TransactionType);
ProcessingSteps := GetConfiguredSteps();
foreach StepName in ProcessingSteps do begin
if not ExecuteProcessingStep(StepName, DataVariant) then
exit(false);
end;
exit(true);
end;
local procedure LoadConfiguration(TransactionType: Enum "Business Transaction Type")
begin
FacadeConfig.SetRange("Transaction Type", TransactionType);
FacadeConfig.SetRange(Active, true);
if not FacadeConfig.FindFirst() then
Error('No configuration found for transaction type %1', TransactionType);
end;
local procedure GetConfiguredSteps(): List of [Text]
var
ConfigLine: Record "Facade Configuration Line";
StepsList: List of [Text];
begin
ConfigLine.SetRange("Configuration ID", FacadeConfig."Configuration ID");
ConfigLine.SetCurrentKey("Step Order");
if ConfigLine.FindSet() then
repeat
StepsList.Add(ConfigLine."Step Name");
until ConfigLine.Next() = 0;
exit(StepsList);
end;
}
```
## Performance-Optimized Facade
```al
codeunit 50205 "Performance Optimized Facade"
{
var
CachedResults: Dictionary of [Text, Variant];
BatchProcessor: Codeunit "Batch Processing Engine";
procedure ProcessMultipleOrders(var SalesHeaders: Record "Sales Header"): Record "Batch Processing Result"
var
BatchJob: Record "Batch Processing Job";
Result: Record "Batch Processing Result";
begin
BatchJob := BatchProcessor.CreateBatchJob('SALES_ORDER_PROCESSING');
// Add all orders to batch
SalesHeaders.FindSet();
repeat
BatchProcessor.AddToBatch(BatchJob, SalesHeaders);
until SalesHeaders.Next() = 0;
// Process batch with optimized resource usage
Result := BatchProcessor.ExecuteBatch(BatchJob);
// Clean up resources
BatchProcessor.CompleteBatch(BatchJob);
exit(Result);
end;
procedure GetCachedCustomerData(CustomerNo: Code[20]): Variant
var
CacheKey: Text;
CustomerData: Variant;
begin
CacheKey := 'CUSTOMER_' + CustomerNo;
if CachedResults.ContainsKey(CacheKey) then
exit(CachedResults.Get(CacheKey));
CustomerData := LoadCustomerData(CustomerNo);
CachedResults.Set(CacheKey, CustomerData);
exit(CustomerData);
end;
procedure ClearCache()
begin
Clear(CachedResults);
end;
}
```
## Error Handling Facade
```al
codeunit 50206 "Error Handling Facade"
{
procedure ExecuteWithErrorHandling(Operation: Interface "Business Operation"; var ErrorInfo: Record "Error Information"): Boolean
var
RetryCount: Integer;
MaxRetries: Integer;
begin
MaxRetries := 3;
RetryCount := 0;
repeat
RetryCount += 1;
if TryExecuteOperation(Operation) then
exit(true);
HandleOperationError(GetLastErrorText(), RetryCount, ErrorInfo);
if ShouldRetry(ErrorInfo, RetryCount, MaxRetries) then
Sleep(CalculateRetryDelay(RetryCount))
else
exit(false);
until RetryCount >= MaxRetries;
exit(false);
end;
[TryFunction]
local procedure TryExecuteOperation(Operation: Interface "Business Operation")
begin
Operation.Execute();
end;
local procedure ShouldRetry(ErrorInfo: Record "Error Information"; RetryCount: Integer; MaxRetries: Integer): Boolean
begin
if RetryCount >= MaxRetries then
exit(false);
case ErrorInfo."Error Type" of
ErrorInfo."Error Type"::"Temporary Network Error",
ErrorInfo."Error Type"::"Database Timeout":
exit(true);
else
exit(false);
end;
end;
}
```
This sample demonstrates complex facade patterns including multi-layer architecture, composition, context-awareness, enterprise integration, configurability, performance optimization, and comprehensive error handling.