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

> Understand DDDplus extension routing differences: Policy for global mapping, Pattern for conditional matching, and Partner for exclusive scopes. Learn how these mechanisms differ and their precedence.

- Repository: [Funky Gao/cp-ddd-framework](https://github.com/funkygao/cp-ddd-framework)
- Tags: deep-dive
- Published: 2026-03-02

---

**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`](https://github.com/funkygao/cp-ddd-framework/blob/main/InternalIndexer.java)** – Located at [`dddplus-runtime/src/main/java/io/github/dddplus/runtime/registry/InternalIndexer.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/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`](https://github.com/funkygao/cp-ddd-framework/blob/main/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`](https://github.com/funkygao/cp-ddd-framework/blob/main/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`](https://github.com/funkygao/cp-ddd-framework/blob/main/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:

```java
@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:

```java
@Pattern(code = "SellerA")
public class SellerAPattern extends BasePattern {
    private boolean match(SellerIdentity identity) {
        return "A".equals(identity.getSellerId());
    }
}

```

```java
@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:

```java
@Partner(code = "LogisticsX")
public class LogisticsXPartner implements IIdentityResolver {
    @Override
    public boolean match(IIdentity identity) {
        return identity instanceof OrderIdentity &&
               ((OrderIdentity) identity).getLogisticsProvider().equals("X");
    }
}

```

```java
@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`](https://github.com/funkygao/cp-ddd-framework/blob/main/InternalIndexer.java), [`PolicyDef.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/PolicyDef.java), [`PatternDef.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/PatternDef.java), and [`PartnerDef.java`](https://github.com/funkygao/cp-ddd-framework/blob/main/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.