Backend Development 17 min read

Mastering COLA: Clean Object‑Oriented Layered Architecture for Scalable Backend Systems

This article explains the COLA (Clean Object‑Oriented and Layered Architecture) framework, its layered structure, component breakdown, and practical implementation details with SpringBoot, including code examples, module organization, and design principles for building maintainable backend systems.

macrozheng
macrozheng
macrozheng
Mastering COLA: Clean Object‑Oriented Layered Architecture for Scalable Backend Systems

The article begins by questioning the characteristics of business code, especially in fast‑moving internet projects, and lists common problems: rapid iteration leading to messy code without comments, frequent personnel changes, inconsistent coding habits among developers, and a lack of time for refactoring, which together cause growing technical debt.

It proposes solutions such as regular team refactoring, designing a robust application architecture, and keeping designs simple so that developers at any level can quickly understand and work with the code.

COLA, the main focus of the article, is introduced as a practical business code structure standard aimed at slowing code decay and improving development efficiency.

What is COLA

COLA stands for Clean Object‑Oriented and Layered Architecture . It was proposed by Alibaba’s Zhang Jianfei and is included as an optional component in Alibaba Cloud’s scaffolding code generator, indicating its influence.

COLA 4.0 splits the framework into two parts: the COLA architecture (Archetype) and COLA components, which can be used independently.

COLA Overall Architecture

The article cites the official COLA blog, noting that most business systems need to receive requests, process business logic, and interact with external systems such as databases, micro‑services, or search engines. This commonality leads to generic architectural ideas like layered, hexagonal, onion, clean, and DDD architectures.

Although many architectural patterns exist, COLA provides concrete, actionable practices rather than just theory, making it a rare open‑source solution at the application architecture level.

COLA offers a ready‑to‑use code architecture that incorporates many design concepts, including domain‑driven design (DDD).

COLA Layered Architecture

Two official diagrams illustrate the overall structure (images omitted for brevity).

The example project follows a Maven parent‑child structure, with the parent pom.xml declaring the following modules:

<code>&lt;modules&gt;
  &lt;module&gt;demo-web-client&lt;/module&gt;
  &lt;module&gt;demo-web-adapter&lt;/module&gt;
  &lt;module&gt;demo-web-app&lt;/module&gt;
  &lt;module&gt;demo-web-domain&lt;/module&gt;
  &lt;module&gt;demo-web-infrastructure&lt;/module&gt;
  &lt;module&gt;start&lt;/module&gt;
&lt;/modules&gt;</code>

Start Layer

The start module is the bootstrapping SpringBoot application that holds global configuration and launch logic, providing a clear entry point for newcomers.

Adapter Layer

The adapter layer corresponds to the traditional controller layer in MVC, handling web, wireless, and WAP requests. It adapts incoming requests to the internal service calls.

With the rise of mobile, most applications now need to support Web, Mobile, and WAP front‑ends, so the adapter layer extends beyond classic MVC controllers.

Client Layer

The client layer defines service interfaces (

api

) and data transfer objects (

dto

) that other modules consume. It does not contain implementation logic; instead, the adapter layer calls these interfaces.

Example client package structure:

api folder – service interface definitions

dto folder – transfer entities

In the adapter layer, a controller injects the client interface:

<code>@RestController
public class CustomerController {
    @Autowired
    private CustomerServiceI customerService;

    @GetMapping(value = "/customer")
    public MultiResponse<CustomerDTO> listCustomerByName(@RequestParam(required = false) String name) {
        CustomerListByNameQry qry = new CustomerListByNameQry();
        qry.setName(name);
        return customerService.listByName(qry);
    }
}</code>

The actual implementation resides in the app layer:

<code>@Service
@CatchAndLog
public class CustomerServiceImpl implements CustomerServiceI {
    @Resource
    private CustomerListByNameQryExe customerListByNameQryExe;

    @Override
    public MultiResponse<CustomerDTO> listByName(CustomerListByNameQry qry) {
        return customerListByNameQryExe.execute(qry);
    }
}</code>

App Layer

The app layer implements business logic, organized first by domain (e.g., customer , order ) and then by function (executors, consumers, schedulers). This separation keeps related code together while isolating cross‑domain concerns.

Typical app sub‑layers include:

executor – handles commands and queries

consumer – processes external messages

scheduler – runs scheduled tasks

Domain Layer

The domain layer encapsulates core business logic through entities, domain services, and gateways. Entities may be rich (e.g.,

Customer

with behavior methods), domain services expose business capabilities, and gateways define SPI interfaces for infrastructure implementations.

<code>@Data
@Entity
public class Customer {
    private String customerId;
    private String memberId;
    private String globalId;
    private long registeredCapital;
    private String companyName;
    private SourceType sourceType;
    private CompanyType companyType;

    public boolean isBigCompany() {
        return registeredCapital > 10000000;
    }

    public boolean isSME() {
        return registeredCapital > 10000 && registeredCapital < 1000000;
    }

    public void checkConfilict() {
        if ("ConflictCompanyName".equals(this.companyName)) {
            throw new BizException(this.companyName + " has already existed, you can not add it");
        }
    }
}</code>
<code>public interface CustomerGateway {
    public Customer getByById(String customerId);
}</code>
<code>@Component
public class CustomerGatewayImpl implements CustomerGateway {
    @Autowired
    private CustomerMapper customerMapper;

    @Override
    public Customer getByById(String customerId) {
        CustomerDO customerDO = customerMapper.getById(customerId);
        // Convert to Customer entity
        return null; // conversion omitted for brevity
    }
}</code>

Infrastructure Layer

The infrastructure layer provides technical details such as MyBatis mappers, configuration files, and gateway implementations, handling database CRUD, external service calls, and other low‑level concerns.

Features of COLA

Domain‑and‑Function Packaging Strategy

Packages are first divided by domain and then by function, preventing code decay from spreading across unrelated modules. For example, customer and order domains each have their own DTOs and utilities, avoiding conflicts.

Decoupling Business Domain from External Dependencies

The dependency inversion between domain and infrastructure layers allows a domain entity (e.g., Item ) to obtain data from various sources—MySQL, Redis, or external APIs—through gateway interfaces, keeping the domain logic independent of concrete data sources.

COLA Is Not Perfect

Although COLA provides a clear structure, it can lead to an explosion of DTOs because each interface often defines its own request and response objects, which may become redundant.

Overall, COLA offers a design philosophy rather than a strict enforcement, allowing teams to adopt the parts that fit their needs while discarding unnecessary complexity.

Conclusion

COLA’s architecture is straightforward and has matured through successive refinements, now being an optional component in Alibaba Cloud’s code generator, demonstrating its stability and adoption.

Javabackend-developmentCOLAclean architecturelayered architectureSpringBoot
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login 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.