Backend

99 Ngày Java — Ngày 90: Tổ chức Project và Clean Code

SSite Admin
25 tháng 10, 2026 3 phút đọc 4 lượt xem
99 Ngày Java — Ngày 90: Tổ chức Project và Clean Code

Code chạy đúng mới là một nửa công việc; nửa còn lại là người sau đọc được và sửa được mà không sợ. Phần lớn thời gian của lập trình viên là đọc code. Bài này gom những quyết định ảnh hưởng nhiều nhất tới việc đọc: chia package thế nào, đặt tên ra sao và giữ hàm ở mức nào thì vừa.

Tổ chức Project và Clean Code

1. Package theo feature

Chia package theo tầng kỹ thuật như controller, service, repository làm một tính năng nằm rải ở ba nơi và buộc gần như mọi lớp phải public. Chia theo feature đặt mọi thứ của một nghiệp vụ vào một package. Khi đó chỉ lớp làm cửa ngõ cần public, phần còn lại để package-private, và trình biên dịch giúp bạn giữ ranh giới giữa các feature.

vn.motdev.shop
├── order
│   ├── OrderController.java     // public entry point
│   ├── OrderService.java        // package-private
│   ├── OrderRepository.java     // package-private
│   └── Order.java
├── payment
│   └── ...
└── shared                        // few, stable, truly common types

2. Tên nói lên ý định

Một cái tên tốt trả lời được biến này là gì hoặc hàm này làm gì mà không cần mở phần thân. Lớp là danh từ, phương thức là động từ, boolean đọc như một câu hỏi có không. Tránh viết tắt và tránh những từ rỗng như data, info, manager, util. Tên dài trong phạm vi rộng, tên ngắn trong phạm vi hẹp. Theo quy ước Java: lớp PascalCase, phương thức và biến camelCase, hằng UPPER_SNAKE_CASE, package chữ thường.

// before
List<Order> list = repo.get(d, true);

// after
List<Order> overdueOrders = orders.findUnpaidBefore(dueDate);
boolean isEligibleForRefund = order.isPaid() && !order.isShipped();

3. Hàm nhỏ, một mức trừu tượng

Một hàm nên làm một việc và các dòng trong nó nên ở cùng một mức trừu tượng: đừng trộn quy tắc nghiệp vụ với chi tiết ghép chuỗi. Guard clause xử lý trường hợp không hợp lệ ngay đầu hàm rồi thoát, để phần chính không bị lồng trong nhiều tầng if. Tham số boolean thường báo hiệu hàm đang làm hai việc; tách thành hai hàm có tên rõ.

Receipt checkout(Order order) {
    if (order.isEmpty()) throw new EmptyOrderException(order.id());
    if (order.isPaid()) return receipts.findByOrder(order.id());

    Money total = pricing.totalFor(order);
    Payment payment = gateway.charge(order.customerId(), total);
    return receipts.issue(order, payment);
}

4. Những nguyên tắc dùng được ngay

Clean code không phải một bộ luật cứng mà là thói quen giảm bất ngờ cho người đọc. Comment nên giải thích vì sao, vì code đã nói làm gì; comment lặp lại code sẽ lỗi thời trước code. Ưu tiên đối tượng bất biến và báo lỗi sớm thay vì trả null. Để công cụ lo phần định dạng để review tập trung vào thiết kế.

  • Xóa code chết; lịch sử đã có trong Git.

  • Trùng lặp ba lần mới trừu tượng hóa; trừu tượng sai tốn hơn trùng lặp.

  • Giữ một cách làm cho một loại việc trong cả codebase.

  • Dùng formatter và linter trong build: Spotless, Checkstyle hoặc Error Prone.

  • Để lại code sạch hơn một chút so với lúc bạn mở nó ra.

Cấu trúc và tên gọi là giao diện giữa bạn và người đọc sau. Ngày 91 mở chặng cuối của series với năm nguyên tắc thiết kế SOLID.

Tài liệu đối chiếu

  • https://google.github.io/styleguide/javaguide.html

  • https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html

S

Site Admin

Engineer and writer. Building things with TypeScript and distributed systems.

Bình luận (0)

Bạn cần đăng nhập bằng Google để bình luận.

Hãy là người bình luận đầu tiên.

Bài viết liên quan

99 Ngày Spring — Ngày 90: Docker Compose cho Dev

compose.yaml cho Postgres, Redis và Kafka, spring-boot-docker-compose tự khởi động và tự nối kết, cùng ranh giới với Testcontainers.

25 thg 10, 20262 phút4
99 Ngày Spring — Ngày 89: Docker hóa Spring Boot

Dockerfile nhiều stage, layered jar để tận dụng cache, chạy không dùng root và buildpacks khi không muốn viết Dockerfile.

23 thg 10, 20263 phút7
99 Ngày Java — Ngày 89: Mockito

mock, stub và verify, @Mock với @InjectMocks, ArgumentCaptor và những gì không nên mock.

23 thg 10, 20263 phút7