Nhảy đến nội dung chính

9.Coding convention

9.1. Mục tiêu chương

Chương này quy định chuẩn coding và nguyên tắc thiết kế nhằm:

  • Đảm bảo code thống nhất giữa các module và các đơn vị phát triển

  • Giúp code dễ đọc, dễ hiểu và dễ bảo trì

  • Giảm lỗi phát sinh do cách đặt tên hoặc coding không đồng nhất

  • Tăng hiệu quả review và kiểm soát chất lượng code

  • Đảm bảo code tuân thủ nguyên lý thiết kế SOLID

  • Đảm bảo kiến trúc backend Spring Boot nhất quán toàn hệ thống


9.2. Khái niệm / phạm vi áp dụng

Quy định này áp dụng cho:

  • Toàn bộ source code của hệ thống

  • Core Team và Partner Team

  • Tất cả các module trong modules/**

  • Các thành phần trong common/**config/** do Core Team quản lý

  • Tất cả service, controller, repository, DTO, entity


9.3. Quy định chính

9.3.1. Quy tắc đặt tên

Các thành phần phải đặt tên theo quy ước thống nhất:

Thành phần Quy tắc đặt tên Ví dụ
Controller <Name>Controller UserController
Service <Name>Service UserService
Repository <Name>Repository UserRepository
Entity <Name>Entity UserEntity
DTO Request <Name>CreateRequest, <Name>UpdateRequest UserCreateRequest
DTO Response <Name>Response UserResponse
Mapper <Name>Mapper UserMapper
Enum <Name>Enum UserStatusEnum

9.3.2. Quy tắc chung Java

Dùng camelCase cho:

  • Biến

  • Method

Dùng PascalCase cho:

  • Class

  • Interface

  • Enum

Ví dụ:


private String fullName; // đúng private String FullName; // sai public class UserService { } // đúng public class userService { } // sai

9.3.3. Quy định về logging

Không được dùng:


System.out.println("Error");

Phải dùng logging chuẩn:


private static final Logger log = LoggerFactory.getLogger(UserService.class); log.info("User created"); log.error("Create user failed", ex);

9.3.4. Validation dữ liệu đầu vào

Tất cả dữ liệu đầu vào phải được validate bằng annotation.

Annotation chuẩn:

  • @NotNull

  • @NotBlank

  • @Size

  • @Email

  • @Pattern

Ví dụ:


public class UserCreateRequest { @NotBlank @Size(max = 100) private String username; @NotBlank private String password; }

9.4. Nguyên lý thiết kế SOLID áp dụng trong dự án

9.4.1. S — Single Responsibility

Một class chỉ có một trách nhiệm.

Quy định dự án:

  • Controller → chỉ xử lý HTTP

  • Service → xử lý nghiệp vụ

  • Repository → truy cập DB

  • Mapper → convert DTO ↔ Entity

Sai:


public class UserController { @Autowired UserRepository repo; // sai tầng }

Đúng:


public class UserController { @Autowired UserService userService; }

9.4.2. O — Open/Closed

Code phải mở rộng được nhưng không sửa code cũ.

Áp dụng:

  • Dùng interface Service

  • Không sửa class gốc khi thêm logic

Ví dụ:


public interface NotificationService { void send(Message msg); }

Triển khai:


public class EmailNotificationService implements NotificationService { } public class SmsNotificationService implements NotificationService { }

9.4.3. L — Liskov Substitution

Class con có thể thay thế class cha.

Quy định:

  • ServiceImpl phải tuân interface

  • Không throw exception mới trái contract

Sai:


public class UserServiceImpl implements UserService { public User get(String id) { throw new UnsupportedOperationException(); } }

9.4.4. I — Interface Segregation

Không tạo interface quá lớn.

Sai:


public interface UserService { create(); update(); delete(); exportExcel(); sendEmail(); }

Đúng:


public interface UserService { } public interface UserExportService { } public interface UserNotificationService { }

9.4.5. D — Dependency Inversion

Phụ thuộc abstraction, không phụ thuộc implementation.

Quy định:

  • Inject interface

  • Không new service

Sai:


UserService service = new UserServiceImpl();

Đúng:


@Autowired UserService userService;

9.5. Quy tắc kiến trúc Spring Boot trong dự án

9.5.1. Luồng chuẩn tầng


Controller → Service → Repository → Database

Không được:


Controller → Repository Controller → EntityManager

9.5.2. Controller không chứa nghiệp vụ

Sai:


@PostMapping public User create(...) { user.setCreatedDate(LocalDateTime.now()); // sai }

Đúng:


@PostMapping public UserResponse create(...) { return userService.create(request); }

9.5.3. Service không chứa logic HTTP

Sai:


throw new ResponseStatusException(HttpStatus.BAD_REQUEST);

Đúng:


throw new BusinessException("USER_EXISTS");

9.5.4. Repository chỉ truy vấn dữ liệu

Không chứa:

  • validation

  • business logic

  • mapping


9.6. Design pattern sử dụng trong hệ thống

9.6.1. Service pattern

Service là tầng nghiệp vụ trung tâm.


Controller → Service → Repository

9.6.2. DTO pattern

Tách DTO khỏi Entity.

Không trả Entity ra API.

Sai:


public UserEntity create(...) { }

Đúng:


public UserResponse create(...) { }

9.6.3. Mapper pattern

Convert DTO ↔ Entity.


UserEntity entity = mapper.toEntity(request);

9.6.4. Exception pattern

Dùng BusinessException thống nhất.


throw new BusinessException(ErrorCode.USER_NOT_FOUND);

9.7. Cách thực hiện / quy trình

Quy trình tạo DTO đúng chuẩn

Bước 1: Tạo class DTO theo quy tắc đặt tên

Ví dụ:

  • UserCreateRequest

  • UserUpdateRequest

  • UserResponse

Bước 2: Thêm validation annotation

Bước 3: Dùng DTO trong controller


@PostMapping public ApiResponse<UserResponse> create( @Valid @RequestBody UserCreateRequest request) { return ApiResponse.ok(userService.create(request)); }

Quy trình logging chuẩn

Bước 1: Khai báo logger trong class


private static final Logger log = LoggerFactory.getLogger(UserService.class);

Bước 2: Dùng logger thay cho System.out.println


9.8. Ví dụ minh họa

Trường hợp sai


public class usercontroller { public void CreateUser() { System.out.println("Create user"); } }

Sai vì:

  • Tên class không đúng chuẩn

  • Tên method không camelCase

  • Dùng System.out.println

  • Không theo kiến trúc tầng


Trường hợp đúng


@RestController public class UserController { private static final Logger log = LoggerFactory.getLogger(UserController.class); private final UserService userService; public UserController(UserService userService) { this.userService = userService; } @PostMapping public ApiResponse<UserResponse> create( @Valid @RequestBody UserCreateRequest request) { log.info("Create user {}", request.getUsername()); return ApiResponse.ok(userService.create(request)); } }

Ví dụ DTO sai


public class userDTO { public String name; }

Sai vì:

  • Tên class không chuẩn

  • Không có validation

  • Field public

  • Không theo DTO pattern


Ví dụ DTO đúng


public class UserCreateRequest { @NotBlank @Size(max = 255) private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }

9.9. Checklist áp dụng

Trước khi commit hoặc tạo PR:

Naming

  • Controller → *Controller

  • Service → *Service

  • Repository → *Repository

  • Entity → *Entity

  • DTO → *Request / *Response


Coding

  • Biến và method dùng camelCase

  • Class dùng PascalCase

  • Không dùng System.out.println

  • Dùng logging chuẩn slf4j


Validation

  • DTO có validation annotation

  • Không có field public trong DTO


SOLID

  • Controller không chứa nghiệp vụ

  • Service không chứa HTTP logic

  • Repository chỉ truy vấn DB

  • Inject interface, không new

  • Class có 1 trách nhiệm


Architecture

  • Không Controller → Repository

  • Không trả Entity ra API

  • Có DTO mapping

  • Exception dùng chuẩn hệ thống