How a 2‑Year Journey Unified Java Backend Code Structure for Better Readability and Maintenance

This article shares a two‑and‑a‑half year effort to standardize code style and architecture across a large Java backend, detailing the origins, evolving patterns, a unified layered model, concrete implementation examples, measurable benefits, and future directions for continuous improvement.

DaTaobao Tech
DaTaobao Tech
DaTaobao Tech
How a 2‑Year Journey Unified Java Backend Code Structure for Better Readability and Maintenance

Background and Motivation

The author reflects on a 2.5‑year practice of improving code style and structural consistency within a team responsible for a complex live‑stream commerce commission system, aiming to reduce errors, lower onboarding cost for newcomers, and make business logic easier to understand.

Evolution of the Service Layer

Early MVC patterns (Controller → Service → DAO) gave way to modern entry services that handle RPC, HTTP, messaging, or scheduled tasks, while DAO‑like layers now call other distributed services. The business‑logic layer (formerly Service) lacked any structural guidance, leading to divergent implementations.

Observed Code Patterns

Simple method split into private helper methods for readability.

Parallel execution using thread pools to shorten response time.

Responsibility‑chain pattern that breaks processing into linked nodes.

Parallel chain with dependency handling.

Strategy‑pattern based on business‑type identifiers, which can proliferate without clear constraints.

Proposed Unified Layered Architecture

The team introduced a standardized hierarchy that can be visualized as:

Layered architecture diagram
Layered architecture diagram

Key layers include:

Entry Service : validates parameters, performs object conversion, and delegates core logic to the business process.

Business Process & Activities : a sequence (or parallel set) of activities that orchestrate domain services; each activity acts as glue code.

Domain & Domain Services : encapsulate the core business capabilities of an entity.

Domain Service Extension Points : generic templates that allow strategy‑pattern extensions for varying business rules.

Implementation Details

Concrete examples illustrate the new structure. An entry service starts a process engine, builds a context, and returns a result:

/**
 * This is an HSF interface Provider implementation, typical try‑catch omitted
 */
@ServiceEntrance(name="Attribution Billing Service")
@Override
public Result<RatingDTO> rating(RatingRequest request) {
    validateRatingParam(request);
    // Build process context and start the workflow
    RatingProcessContext context = new RatingProcessContext();
    context.setRatingRequest(request);
    ProcessResult processResult = processEngine.start(ProcessNS.PROCESS_RATING, context);
    if (processResult.isSuccess()) {
        return Result.success(buildRatingResultDTO(context));
    } else {
        return Result.fail(processResult.getErrorCode(), processResult.getErrorMessage());
    }
}

The corresponding XML process definition shows sequential and parallel activities:

<?xml version="1.0" encoding="UTF-8"?>
<onion-process-config>
  <!-- Basic logical orchestration: sequence, parallel, condition, loop, etc. Most used is simple sequence -->
  <process id="rating_process" name="Content Attribution Billing Process">
    <node-list>
      <activity name="Initialize Data" bean="ratingInitActivity"/>
      <activity name="Online Attribution" bean="ratingAttributeActivity"/>
      <activity name="Post‑Attribution Init" bean="ratingAttributeAfterInitActivity"/>
      <activity name="Blacklist Check" bean="ratingBlackCheckActivity"/>
      <activity name="Calculate Ratio" bean="ratingRatioActivity"/>
      <activity name="Sync Accounting" bean="ratingAutoPayCenterActivity"/>
      <activity name="Init External Track" bean="ratingInitOuterTrackRuleActivity"/>
      <activity name="Build Commission List" bean="ratingCommissionListActivity"/>
      <activity name="Build Extra Commission" bean="ratingExtraCommissionListActivity"/>
      <activity name="Assemble Result" bean="ratingResultBuildActivity"/>
    </node-list>
  </process>
  <!-- Parallel example -->
  <process id="itemCompleteParallelProcess" name="Item Completion Process" parallel="true" executor="itemCompleteExecutor" timeout="500">
    <node-list>
      <activity name="Activity A" bean="itemCompleteActivityA"/>
      <activity name="Activity B" bean="itemCompleteActivityB"/>
      <activity name="Activity C" bean="itemCompleteActivityC"/>
      <activity name="Activity D" bean="itemCompleteActivityD"/>
      <activity name="Activity E" bean="itemCompleteActivityE"/>
      <activity name="Activity F" bean="itemCompleteActivityF">
        <dependency-list>
          <!-- F depends on A completing first -->
          <dependency ref="itemCompleteActivityA"/>
        </dependency-list>
      </activity>
    </node-list>
  </process>
</onion-process-config>

Domain service examples show how attribution and billing logic are encapsulated and how strategy extensions are invoked:

@Domain(id = DomainNS.DOMAIN_TCP_RATING, name = "Attribution Billing Domain")
public class RatingDomainService implements IDomainService<TcpRatingExtTemplate> {
    /** Attribution domain service */
    @DomainService(name="Attribution Service")
    public AttributeResultDTO attributeTo(AttributeToRequest request) {
        List<TcpTrackDTO> trackList = request.getRatingRequest().getTrackList();
        TcpTrackDTO lastClick = trackList.get(trackList.size() - 1);
        AttributeResultDTO result = new AttributeResultDTO();
        result.setBizcode(lastClick.getBizcode());
        result.setTrackDTO(lastClick);
        return result;
    }
    /** Billing domain service */
    @DomainService(name="Billing Service")
    public List<RatingDetailDTO> ratioCalculate(RatioCalculateRequest request) {
        List<RatingDetailDTO> resultList = Lists.newLinkedList();
        for (RatioCalculateInstance instance : request.getRatingInstance().getRatioCalculateInstanceList()) {
            BizTypeRatingInput input = new BizTypeRatingInput();
            input.setInstance(instance);
            BizTypeRatingOutput output = this.invokeFirstMatched(instance,
                TcpRatingExtTemplate.EXT_TCP_BIZTYPE_RATING,
                ext -> ext.bizTypeRating(input));
            if (output != null) {
                resultList.addAll(output.getRatingDetailList());
            }
        }
        return resultList;
    }
}

Benefits and Results

12 backend services migrated to the new model.

Over 600 entry services, 400+ processes, 180+ domains, and more than 1,000 domain services now follow the same structure.

Code readability improved: developers can locate a process file and instantly understand the workflow.

Consistent patterns reduce learning cost when moving between domains.

Standardization enables visual tooling (IDE plugins) for navigation and architecture inspection.

Future Directions

Planned work includes adding monitoring and alerting at each architectural layer, leveraging the standardized model for AI‑assisted code generation, and further exploring advanced orchestration features such as sub‑processes, groups, and custom composers to balance declarative workflow definitions with hand‑written Java when necessary.

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.

backend architecturesoftware engineeringDomain-Driven Designcode styleCode OrganizationService Layer
DaTaobao Tech
Written by

DaTaobao Tech

Official account of DaTaobao Technology

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.