DDDplus Extension Routing: How Pattern, Partner, and Policy Mechanisms Differ

DDDplus resolves domain extension implementations through three distinct routing strategies—Policy for global identity-to-code mapping, Pattern for priority-ordered conditional matching, and Partner for mutually exclusive vertical business scopes—consulted in strict precedence within InternalIndexer.findEffectiveExtensions.

The funkygao/cp-ddd-framework provides a lightweight yet powerful extension mechanism that enables domain-driven design patterns in Java applications. At the core of this system lies a sophisticated routing engine that determines which extension implementation to execute based on runtime identity. Understanding how DDDplus extension routing differentiates between Policy, Pattern, and Partner mechanisms is crucial for architects designing multi-tenant or vertically-differentiated business logic.

The Three Routing Mechanisms in DDDplus

Policy Routing: Global Deterministic Mapping

Policy routing represents a global business rule that maps an IIdentity directly to an extension code. This mechanism provides O(1) lookup performance and is ideal for deterministic, business-wide classifications such as VIP customer tiers or regional mandates.

In the source code, policies are registered via the @Policy annotation and stored in PolicyDef instances within the policyDefMap. When InternalIndexer.findEffectiveExtensions executes, it first checks this map to resolve the extension code for the given identity.

Pattern Routing: Priority-Ordered Fine-Grained Matching

Pattern routing enables fine-grained, conditional matching through priority-ordered matchers. Unlike policies, patterns can group multiple extensions under a single pattern code and are evaluated sequentially based on assigned priority values (lower values execute first).

Patterns are defined using the @Pattern annotation and encapsulated in PatternDef objects. During the indexing phase in InternalIndexer.postIndexing(), the framework builds a sortedPatternMap where pattern definitions are sorted by priority. At runtime, findEffectiveExtensions iterates through this sorted list, invoking patternDef.match(identity) until a match is found.

Partner Routing: Vertical Business Isolation

Partner routing supports vertically-scoped business logic where extensions belong to specific, mutually exclusive partners such as logistics providers or payment gateways. This mechanism ensures that only one partner's extension is active for a given identity, enforcing vertical isolation.

Partners are registered via the @Partner annotation and represented by PartnerDef instances. Each PartnerDef implements IIdentityResolver to determine if an identity belongs to that partner's scope. During lookup, findEffectiveExtensions walks through partnerDefMap.values(), and the first partner whose match method returns true contributes its extension implementation.

How DDDplus Resolves Extension Routing Order

The resolution algorithm in InternalIndexer.findEffectiveExtensions follows a strict precedence to ensure deterministic behavior:

  1. Policy Check – The method first attempts to resolve the extension via policyDefMap. If a PolicyDef exists for the extension class, it calls policyDef.getExtension(identity) to retrieve the exact extension code.

  2. Pattern Evaluation – If no policy matches, the method retrieves the sorted list of PatternDef objects from sortedPatternMap. It iterates through these patterns in priority order, calling patternDef.match(identity) followed by patternDef.getExtension(extClazz) upon a successful match.

  3. Partner Resolution – If patterns fail to match, the framework falls back to partnerDefMap. It iterates through all registered PartnerDef instances, invoking partnerDef.match(identity) and returning the first matching partner's extension.

If none of these mechanisms yield a result, DDDplus falls back to the default extension defined by IDomainExtension.DefaultCode.

Implementation Details: Core Source Files

Understanding the internal registry structure clarifies how these routing types coexist:

  • InternalIndexer.java – Located at dddplus-runtime/src/main/java/io/github/dddplus/runtime/registry/InternalIndexer.java, this class maintains the policyDefMap, sortedPatternMap, and partnerDefMap. Its findEffectiveExtensions method implements the routing precedence logic.

  • PolicyDef.java – Stores the policy bean and maps extension codes to ExtensionDef instances. The extClazzOfPolicy method extracts the extension class from the policy definition.

  • PatternDef.java – Encapsulates pattern metadata including priority and the set of extension classes it manages. It provides the match and getExtension methods used during pattern routing.

  • PartnerDef.java – Implements IIdentityResolver and holds the partner-specific extension mappings. It ensures vertical business isolation by matching identities against partner-specific criteria.

Code Examples

Defining a Policy Extension

Policies provide global routing based on business rules:

@Policy
public class FooPolicy implements IPolicy<FooExt, FooIdentity> {
    @Override
    public String extensionCode(FooIdentity identity) {
        // Business-wide rule: VIP customers use "vipFoo"
        return identity.isVip() ? "vipFoo" : "standardFoo";
    }
}

When InternalIndexer.findEffectiveExtensions processes a FooExt request, it consults FooPolicy first to determine which extension code to activate.

Defining a Pattern Extension

Patterns enable fine-grained, prioritized matching:

@Pattern(code = "SellerA")
public class SellerAPattern extends BasePattern {
    private boolean match(SellerIdentity identity) {
        return "A".equals(identity.getSellerId());
    }
}
@Extension(code = "SellerA")
public class SellerAExtension implements FooExt {
    // Implementation specific to Seller A
}

The framework indexes this pattern in sortedPatternMap and evaluates it according to its priority value during the pattern routing phase.

Defining a Partner Extension

Partners isolate vertical business capabilities:

@Partner(code = "LogisticsX")
public class LogisticsXPartner implements IIdentityResolver {
    @Override
    public boolean match(IIdentity identity) {
        return identity instanceof OrderIdentity &&
               ((OrderIdentity) identity).getLogisticsProvider().equals("X");
    }
}
@Extension(code = "LogisticsX")
public class LogisticsXExtension implements FooExt {
    // Logistics provider X specific logic
}

During partner routing, InternalIndexer iterates through partnerDefMap and selects the first matching partner, ensuring only one vertical extension is active.

Summary

DDDplus implements a sophisticated three-tier extension routing system:

  • Policy routing provides O(1) global identity-to-extension mapping via PolicyDef and the @Policy annotation, evaluated first in InternalIndexer.findEffectiveExtensions.

  • Pattern routing enables priority-ordered conditional matching through PatternDef and @Pattern, allowing fine-grained business rules to override policies when necessary.

  • Partner routing supports vertical business isolation via PartnerDef and @Partner, ensuring mutually exclusive partner capabilities are selected only when policy and pattern routing yield no match.

This hierarchical resolution strategy—implemented across InternalIndexer.java, PolicyDef.java, PatternDef.java, and PartnerDef.java—ensures deterministic extension selection while supporting complex, multi-dimensional business variations.

Frequently Asked Questions

What is the exact precedence order for DDDplus extension routing?

The framework evaluates routing mechanisms in the following strict sequence: first Policy, then Pattern, and finally Partner. This hierarchy is hardcoded in InternalIndexer.findEffectiveExtensions, where the method first checks policyDefMap, then iterates sortedPatternMap, and lastly walks through partnerDefMap.values(). If all three fail to match, the system falls back to the default extension code.

When should I use Pattern routing versus Partner routing in DDDplus?

Use Pattern routing when you need fine-grained, priority-based conditional logic that can coexist with other patterns or when multiple matching rules might apply to different aspects of an identity. Patterns are ideal for seller-specific logic or feature flags. Use Partner routing when implementing vertically-isolated business capabilities where only one provider should be active for a given identity, such as logistics partners or payment gateways that are mutually exclusive by business contract.

How does DDDplus handle multiple matching patterns for the same extension?

When multiple patterns match the same identity and extension type, DDDplus selects the implementation based on priority order. During the indexing phase in InternalIndexer.postIndexing(), the framework sorts all PatternDef instances by their priority value (lower values execute first). During resolution in findEffectiveExtensions, the method iterates through this sorted list and returns the extension from the first pattern that returns true from its match method.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →