# Implementing Device Modeling (Thing Model) in KCloud-Platform-IoT: Clean Architecture Guide

> Implement device modeling using Thing Model in KCloud-Platform-IoT. This guide details a four-layer clean architecture for robust IoT solutions with MyBatis-Plus persistence.

- Repository: [laokou/kcloud-platform-iot](https://github.com/koushenhai/kcloud-platform-iot)
- Tags: architecture
- Published: 2026-03-05

---

**KCloud-Platform-IoT implements device modeling through a four-layer clean architecture separating Domain, Application, Infrastructure, and Client concerns, using ThingModelE as the core entity with MyBatis-Plus persistence and bidirectional DTO conversion.**

The **Thing Model** (device-model) serves as the central entity describing device data points, events, and commands in the `koushenhai/kcloud-platform-iot` repository. This implementation demonstrates how to structure complex IoT domain logic using Spring Boot, MyBatis-Plus, and strict layer isolation. Understanding this architecture allows developers to extend device capabilities while maintaining testable, maintainable code boundaries.

## Clean Architecture Layers Overview

The implementation strictly follows clean architecture principles with four distinct layers. Each layer has specific responsibilities and dependency directions pointing inward toward the Domain.

- **Domain**: Encapsulates business rules, validation, and entity definitions in `ThingModelE`
- **Application**: Orchestrates use-cases through `ThingModelDomainService`
- **Infrastructure**: Handles MySQL persistence via MyBatis-Plus and entity conversion
- **Client**: Defines API contracts with command objects like `ThingModelSaveCmd`

This structure ensures that business logic remains independent of storage mechanisms and transport protocols.

## Domain Layer: Entities and Validation

The Domain layer contains the pure business logic for device modeling, isolated from external frameworks.

### ThingModelE Entity Definition

The `ThingModelE` class in [`laokou-service/laokou-iot/laokou-iot-domain/src/main/java/org/laokou/iot/thingModel/model/ThingModelE.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/laokou-service/laokou-iot/laokou-iot-domain/src/main/java/org/laokou/iot/thingModel/model/ThingModelE.java) represents the logical state of a device model:

```java
public class ThingModelE {
    private Long id;
    private String name;
    private String code;
    private String dataType;          // integer, string, decimal, boolean
    private Integer category;         // 1=属性, 2=事件
    private String type;              // read/write/report
    private Integer sort;
    private String specs;             // rule description
    private String remark;
    private OperateType operateType;  // SAVE or MODIFY
    
    public void checkThingModelParam() throws Exception { 
        // validation hook implementation
    }
}

```

### Validation and Factory Patterns

**`ThingModelParamValidator`** enforces uniqueness constraints on the `code` and `name` fields during insertion and ensures required fields are present. Located in [`laokou-service/laokou-iot/laokou-iot-app/src/main/java/org/laokou/iot/thingModel/service/validator/ThingModelParamValidator.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/laokou-service/laokou-iot/laokou-iot-app/src/main/java/org/laokou/iot/thingModel/service/validator/ThingModelParamValidator.java), this validator prevents duplicate device model definitions.

**`ThingModelFactory`** provides Spring-managed prototype instantiation of `ThingModelE` entities, located in the domain module's factory package. This pattern decouples entity creation from the application layer.

## Application Layer: Use Case Orchestration

The `ThingModelDomainService` class in [`laokou-service/laokou-iot/laokou-iot-domain/src/main/java/org/laokou/iot/thingModel/ability/ThingModelDomainService.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/laokou-service/laokou-iot/laokou-iot-domain/src/main/java/org/laokou/iot/thingModel/ability/ThingModelDomainService.java) coordinates all Thing Model operations. It validates entities using `ThingModelParamValidator` before delegating to the infrastructure gateway.

Key methods include:
- `createThingModel(ThingModelE entity)` – Handles new device model creation
- `updateThingModel(ThingModelE entity)` – Manages modification workflows  
- `deleteThingModel(Long[] ids)` – Executes batch deletion

This service acts as the transactional boundary, ensuring business rules execute atomically before persistence.

## Infrastructure Layer: Persistence and Conversion

Infrastructure concerns are isolated in the `laokou-iot-infrastructure` module, implementing the repository pattern through MyBatis-Plus.

### Data Objects and Database Mapping

**`ThingModelDO`** in [`laokou-service/laokou-iot/laokou-iot-infrastructure/src/main/java/org/laokou/iot/thingModel/gatewayimpl/database/dataobject/ThingModelDO.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/laokou-service/laokou-iot/laokou-iot-infrastructure/src/main/java/org/laokou/iot/thingModel/gatewayimpl/database/dataobject/ThingModelDO.java) maps directly to the `iot_thing_model` table. The corresponding **`ThingModelMapper`** interface extends MyBatis-Plus `BaseMapper` for CRUD operations.

### Gateway Implementation

The **`ThingModelGateway`** interface defines the port used by the domain layer, while **`ThingModelGatewayImpl`** in [`gatewayimpl/ThingModelGatewayImpl.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/gatewayimpl/ThingModelGatewayImpl.java) provides the concrete implementation. This adapter converts domain entities to data objects and orchestrates database transactions through `ThingModelMapper.insert()`.

### Type Conversion Strategy

**`ThingModelConvertor`** handles bidirectional mapping between three representations:
- `ThingModelE` (Domain entity)
- `ThingModelDO` (Infrastructure data object)  
- `ThingModelCO` (Client presentation object)

Located in [`gatewayimpl/convertor/ThingModelConvertor.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/gatewayimpl/convertor/ThingModelConvertor.java), this class ensures type safety when crossing architectural boundaries.

## Client Layer: API Contracts

The Client layer defines the external API surface through command objects and service interfaces.

**`ThingModelsServiceI`** in [`laokou-service/laokou-iot/laokou-iot-client/src/main/java/org/laokou/iot/thingModel/api/ThingModelsServiceI.java`](https://github.com/koushenhai/kcloud-platform-iot/blob/main/laokou-service/laokou-iot/laokou-iot-client/src/main/java/org/laokou/iot/thingModel/api/ThingModelsServiceI.java) declares the service contract implemented by HTTP controllers.

Command classes carry request data:
- **`ThingModelSaveCmd`** – Create new model requests
- **`ThingModelModifyCmd`** – Update existing models  
- **`ThingModelRemoveCmd`** – Delete by ID arrays
- **`ThingModelPageQry`** – Paginated queries

**`ThingModelCO`** serves as the client-side representation for API responses, located in the `dto/clientobject` package.

## Practical Implementation Example

Below is a complete controller implementation demonstrating the end-to-end flow for creating a Thing Model:

```java
@RestController
@RequestMapping("/thing-model")
public class ThingModelController {

    @Autowired
    private ThingModelDomainService thingModelDomainService;

    @PostMapping
    public Result<Long> create(@RequestBody ThingModelSaveCmd cmd) throws Exception {
        // Convert command to domain entity using infrastructure convertor
        ThingModelE entity = ThingModelConvertor.toEntity(cmd.getCo(), true);
        
        // Execute domain logic with validation and persistence
        thingModelDomainService.createThingModel(entity);
        
        // Return generated primary key assigned by MyBatis-Plus
        return Result.success(entity.getPrimaryKey());
    }
}

```

The execution flow follows this sequence:
1. **API Layer** receives `ThingModelSaveCmd` extending `CommonCommand`
2. **`ThingModelConvertor.toEntity()`** transforms the command into `ThingModelE`
3. **`ThingModelDomainService.createThingModel()`** validates via `ThingModelParamValidator` and delegates to the gateway
4. **`ThingModelGatewayImpl`** converts to `ThingModelDO` and inserts via `ThingModelMapper`

Update operations follow an identical pattern using `ThingModelModifyCmd` and `updateThingModel()`, while deletion accepts ID arrays through `deleteThingModel()`.

## Summary

The Thing Model implementation in KCloud-Platform-IoT demonstrates production-ready clean architecture for IoT device management:

- **Domain isolation** keeps business rules in `ThingModelE` and `ThingModelParamValidator` independent of frameworks
- **Application orchestration** through `ThingModelDomainService` provides clear use-case boundaries
- **Infrastructure abstraction** via `ThingModelGatewayImpl` and MyBatis-Plus enables swappable persistence strategies
- **Client contracts** using command objects (`ThingModelSaveCmd`, `ThingModelModifyCmd`) ensure API stability

The conversion flow between `ThingModelCO`, `ThingModelE`, and `ThingModelDO` maintains type safety across all four architectural layers.

## Frequently Asked Questions

### How does KCloud-Platform-IoT validate Thing Model uniqueness?

The platform validates uniqueness through `ThingModelParamValidator` in the Application layer, which checks that the combination of `code` and `name` fields does not already exist in the `iot_thing_model` table before allowing insertion. This prevents duplicate device model definitions while keeping validation logic out of the infrastructure layer.

### What database table stores the Thing Model entities?

Thing Model data persists to the `iot_thing_model` table via `ThingModelDO` and `ThingModelMapper` in the Infrastructure layer. The implementation uses MyBatis-Plus for CRUD operations, with the gateway pattern abstracting database specifics from the Domain layer.

### Can the Thing Model support custom data types beyond integer, string, decimal, and boolean?

Yes. While the reference implementation includes standard IoT data types (integer, string, decimal, boolean) in the `dataType` field of `ThingModelE`, the domain model is extensible. Developers can modify the validation logic in `checkThingModelParam()` and update the database schema to support additional complex types or structured specifications within the `specs` JSON field.

### How does the architecture handle the conversion between API requests and database entities?

The architecture uses `ThingModelConvertor` to handle bidirectional mapping between three representations: `ThingModelCO` (Client/API), `ThingModelE` (Domain), and `ThingModelDO` (Infrastructure). This conversion happens at the architectural boundaries—when entering the Domain from the Client layer and when persisting to the database through the Gateway implementation.