Objective Understanding of DDD and Its Practice in ZuanZuan Pricing System

This article objectively explains Domain‑Driven Design, compares it with traditional data‑driven approaches, and details how DDD was applied in the architecture, strategic and tactical design, context integration, and business‑logic implementation of ZuanZuan's complex pricing system, including code examples.

Zhuanzhuan Tech
Zhuanzhuan Tech
Zhuanzhuan Tech
Objective Understanding of DDD and Its Practice in ZuanZuan Pricing System

Objective Understanding of DDD

DDD (Domain‑Driven Design) provides a new set of concepts and a design mindset for building large, complex software systems, contrasting with the traditional data‑driven design often used in small‑to‑medium projects that can lead to blurred module boundaries and heavy coupling.

Eric Evans summarized DDD theory, but the practice can be adapted to the specific business, team, and technical context; the goal is to keep the architecture stable, clear, and maintainable without blindly copying every concept.

DDD in the ZuanZuan Pricing System: Practice Process

Business Understanding

The pricing system (estimator) is a complex platform that calculates prices and grades for various recycling and retail scenarios, converting inspection reports into valuation items and then applying appropriate pricing flows.

Because different scenarios (C2B online, store recycling, B2C marketplace, etc.) require distinct configurations and pricing methods, a "scenario" concept is introduced to bind parameters and pricing strategies.

Inspection reports generated by professional engineers contain detailed item data; this data must be transformed into maintenance‑friendly valuation items for operations staff.

After valuation items are prepared, the system executes a valuation process that encapsulates one or more pricing methods (e.g., manual price tables, grade pricing, algorithmic models) and selects the appropriate method based on the scenario.

The overarching goal is to build an architecture that is well‑structured, highly testable, low in learning cost, and easy to extend and maintain.

Strategic Design

Based on business analysis, the following sub‑domains are identified:

Scenario sub‑domain (generic, provides configuration parameters for other domains)

Inspection Report Parsing sub‑domain (support, supplies data for valuation)

Valuation Item Conversion sub‑domain (support, supplies data for valuation)

Pricing Flow sub‑domain (support, encapsulates the workflow)

Pricing Method sub‑domain (core, implements the actual pricing calculations)

Tactical Design

Bounded contexts are created for each sub‑domain. For example, the Inspection Report Parsing context models entities (inspection report) and value objects (category, brand, model, items) and uses an anti‑corruption layer to adapt external inspection services.

Context Integration

Integration relationships such as "collaborator", "open host service / published language", and "anti‑corruption layer" are used to define dependencies between bounded contexts and external systems.

Architecture Design

A loosely‑coupled layered architecture is chosen for its low learning curve: API layer (interface definitions), Application layer (application services), Domain layer (core business logic), and Infrastructure layer (data access and external adapters). Common utilities are placed in a separate "common" package.

The project structure looks like:

evaluation_sys
 - api
 - application
 - domain
 - infrastructure
 - common

Business Logic Implementation

Traditional MVC three‑layer designs often lead to fat services where domain entities become mere data carriers. DDD encourages placing behavior inside domain objects and using application services to orchestrate domain services, resulting in clearer separation of concerns.

Example of an application service that evaluates a price:

public EvaluateResult eval(Scenario scenario, EvaluateContext context) {
    // obtain inspection report
    QcReport report = qcReportService.parseReport(context.getQcCode());
    // convert to valuation items
    EvaluateItems evaluateItems = evaluateItemsService.transfer(report, scenario);
    // execute valuation process
    EvaluateResult result = evaluateProcessService.evaluate(scenario, context, evaluateItems);
    // return result
    return result;
}

The domain service that runs the valuation process demonstrates how algorithms are selected and applied:

public class EvaluateProcessService {
    public EvaluateResult evaluate(Scenario scenario, EvaluateContext context, EvaluateItems evaluateItems) {
        // get pricing algorithms
        List<EvaluateAlgorithm> algorithms = EvaluateAlgorithmFactory.create(scenario);
        // create valuation process
        EvaluateProcess process = EvaluateProcessFactory.create(scenario, context, algorithms, evaluateItems);
        // execute process
        return process.evaluate();
    }
}

A concrete implementation that picks the highest price among algorithms:

/**
 * Implementation that returns the maximum price
 */
public class MaxPriceEvaluateProcess implements EvaluateProcess {
    private Scenario scenario;
    private EvaluateProcess context;
    private List<EvaluateAlgorithm> algorithms;
    private EvaluateItems evaluateItems;

    /**
     * Calculates the price
     */
    public EvaluateResult evaluate() {
        long maxPrice = 0;
        // iterate algorithms and calculate price
        for (EvaluateAlgorithm algorithm : algorithms) {
            long price = algorithm.calculate(context, evaluateItems);
            if (maxPrice < price) {
                maxPrice = price;
            }
        }
        return new EvaluateResult(maxPrice);
    }
}

Through systematic decomposition and organization, the code becomes highly readable, aligns with human reasoning, and is easier to maintain and extend.

Conclusion

Practicing DDD requires substantial effort to learn its theory, concepts, and case studies; many decisions and trade‑offs arise. It is essential to clarify the purpose and avoid adopting DDD merely as a trend. Only the parts that truly solve the project's problems should be applied.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSoftware ArchitectureDDD
Zhuanzhuan Tech
Written by

Zhuanzhuan Tech

A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.